2010-03-12 31 views
8

Tôi đến từ Flex nơi bạn có thể làm bất cứ thứ gì bên trong dấu ngoặc nhọn. Tôi đang cố gắng để có được một TextBlock để hiển thị ngày và giờ của ngày hôm nay mà không cần mã hóa nó trong C#. Tôi đã thử nhiều biến thể khác nhau sau đây mà không có may mắn.Ngày hiện tại trong Silverlight XAML TextBlock

TextBlock Text="{Source=Date, Path=Now, StringFormat='dd/MM/yyyy'}" 

Tôi biết tôi có thể có lẽ chỉ cần thiết lập một tài sản MyDate và bám vào đó, nhưng tại sao tôi không thể liên kết trực tiếp đến DateTime.Now bất động sản?

Trả lời

14

Ràng buộc trong Silverlight yêu cầu đối tượng Nguồn hoặc đối tượng Phụ thuộc. Từ đối tượng nguồn đó, bạn có thể liên kết với các thuộc tính (do đó theo định nghĩa bạn ràng buộc với các cá thể thành viên) hoặc các thuộc tính phụ thuộc.

DateTime.Now là thuộc tính tĩnh, bạn không thể liên kết trực tiếp với nó trong Silverlight, do đó cần có một số mã. Điều tốt nhất tiếp theo là sử dụng mã để: -

  • đảm bảo như phần lớn những gì bạn cần thể được thể hiện trong XAML
  • để làm như vậy một cách như de-coupled càng tốt.

Do đó chúng tôi có thể phân tích rằng chúng tôi cần hai điều.

  1. Expose các thành viên tĩnh của DateTime như tài sản thể hiện của một số đối tượng
  2. Có một số cách để định dạng DateTime cho một đầu ra mong muốn.

Xử lý mục đầu tiên tôi sẽ tạo ra một lớp StaticSurrogate, nơi tôi sẽ tạo ra tính chất ví dụ cho các thuộc tính tĩnh mà chúng ta cần truy cập vào: -

public class StaticSurrogate 
{ 
    public DateTime Today { get { return DateTime.Today; } } 
    public DateTime Now { get { return DateTime.Now; } } 
} 

Bây giờ chúng ta cần một cách để định dạng một Ngày giờ. Một chuyển đổi giá trị là công cụ thích hợp cho công việc này, mượn rất nhiều từ này Tim Heuer Blog: -

public class FormatConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (parameter != null) 
     { 
      string formatterString = parameter.ToString(); 

      if (!String.IsNullOrEmpty(formatterString)) 
      { 
       return String.Format(culture, String.Format("{{0:{0}}}", formatterString), value); 
      } 
     } 

     return (value ?? "").ToString(); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Với hai loại cổ phiếu này tại chỗ chúng tôi bây giờ có thể làm phần còn lại trong XAML, trước hết chúng ta cần thể hiện của các lớp này trong các nguồn lực của chúng tôi : -

<UserControl.Resources> 
    <local:StaticSurrogate x:Key="Static" /> 
    <local:FormatConverter x:Key="Formatter" />  
</UserControl.Resources> 

Bây giờ chúng ta có thể cấp điện cho thiết TextBlock: -

<TextBlock Text="{Binding Today, Source={StaticResource Static}, 
    Converter={StaticResource Formatter}, ConverterParameter='dd MMM yyy'}" /> 

Lưu ý rằng phương pháp này có những ưu điểm sau: -

  • chúng tôi không cần phải thêm mã vào UserControl mà trên đó TextBlock được đặt, cũng như chúng ta không phải loay hoay với bất kỳ ngữ cảnh dữ liệu nào.
  • Tài nguyên tĩnh có thể được đặt trong các tài nguyên App.Resources sẽ làm cho việc tạo TextBlock hoàn toàn độc lập với việc phải thêm bất kỳ thứ gì khác vào UserControl.
  • Định dạng được sử dụng để hiển thị ngày có thể được sửa đổi độc lập.
  • Truy cập vào các thuộc tính tĩnh bổ sung có thể dễ dàng được thêm vào lớp StaticSurrogate.
+0

Điều đó làm cho ý nghĩa với tôi nhưng nó không có vẻ cực đoan so với cú pháp Flex: text = "{new Date()}". Tôi đoán tất cả những điều này sẽ tóm tắt một thực tế là Silverlight chỉ hỗ trợ một vài phần mở rộng Markup bên trong XAML. Nó sẽ được tốt đẹp nếu họ thực hiện đánh giá cú đúp xoăn mạnh mẽ hơn mặc dù. Cảm ơn bạn đã giúp đỡ! –

7

Thậm chí nếu bạn có thể khai báo DateTime.Now trong XAML của Silverlight (vì bạn có thể trong WPF - http://soumya.wordpress.com/2010/02/12/wpf-simplified-part-11-xaml-tricks/), bạn có vấn đề là thời gian của bạn sẽ không cập nhật. Nếu bạn sử dụng bộ hẹn giờ cục bộ cập nhật vào lần thứ hai, bạn có thể đảm bảo rằng thời gian của bạn cũng sẽ cập nhật.

public class LocalTimer : INotifyPropertyChanged 
{ 
    private DispatcherTimer timer; 

    public LocalTimer() 
    { 
     timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromSeconds(1.0); 
     timer.Tick += new EventHandler(TimerCallback); 
     this.TimeFormat = "hh:mm:ss"; 
     this.DateFormat = "dddd, MMMM dd"; 
    } 

    private void TimerCallback(object sender, EventArgs e) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs("FormattedDate")); 
     PropertyChanged(this, new PropertyChangedEventArgs("FormattedTime")); 
    } 

    public bool Enabled 
    { 
     get { return this.timer.IsEnabled; } 
     set { if (value) this.timer.Start(); else this.timer.Stop(); } 
    } 

    public string FormattedDate { get { return DateTime.Now.ToString(this.DateFormat); } set {} } 
    public string FormattedTime { get { return DateTime.Now.ToString(this.TimeFormat); } set{} } 

    public string TimeFormat { get; set; } 
    public string DateFormat { get; set; } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    #endregion 
} 

Khai báo một thể hiện của điều này trong XAML ala:

<local:LocalTimer x:Key="theTime" Enabled="True" /> 

và sử dụng các ràng buộc để đảm bảo rằng thời gian của bạn luôn phản ánh.

<TextBlock Text="{Binding Source={StaticResource theTime}, Path=FormattedDate, Mode=OneWay}" x:Name="TodaysDate" /> 
<TextBlock Text="{Binding Source={StaticResource theTime}, Path=FormattedTime, Mode=OneWay}" x:Name="CurrentTime" /> 
+0

Đây có phải là phương pháp hay nhất hoặc có cách cập nhật thanh lịch hơn không? – fzl

1
xmlns:sys="clr-namespace:System;assembly=mscorlib" 

Text="{Binding Source={x:Static sys:DateTime.Today}, StringFormat='Today is {0:dddd, MMMM dd}'}" 
+0

Không thể trực tiếp làm điều này trong Silverlight, xem- http://stackoverflow.com/questions/3373926/silverlight-4-equivalent-to-wpf-xstatic – davidsleeps

+0

Đây là lý do tại sao WPF là tuyệt vời. –

Các vấn đề liên quan