我来自 Flex,在那里你可以在花括号内做任何事情。我正在尝试TextBlock
显示今天的日期和时间,而不仅仅是用 C# 编码。我尝试了以下许多不同的变体,但没有运气。
TextBlock Text="{Source=Date, Path=Now, StringFormat='dd/MM/yyyy'}"
我知道我可能只设置一个属性MyDate
并绑定到该属性,但为什么我不能直接绑定到该DateTime.Now
属性?
我来自 Flex,在那里你可以在花括号内做任何事情。我正在尝试TextBlock
显示今天的日期和时间,而不仅仅是用 C# 编码。我尝试了以下许多不同的变体,但没有运气。
TextBlock Text="{Source=Date, Path=Now, StringFormat='dd/MM/yyyy'}"
我知道我可能只设置一个属性MyDate
并绑定到该属性,但为什么我不能直接绑定到该DateTime.Now
属性?
Silverlight 中的绑定需要 Source 对象或 Dependency 对象。您可以从该源对象绑定到属性(因此根据定义,您绑定到实例成员)或依赖属性。
由于DateTime.Now
是静态属性,因此您无法在 Silverlight 中直接绑定到它,因此需要一些代码。下一个最好的事情是使用代码:-
因此,我们可以分析我们需要两件事。
为了处理第一项,我将创建一个StaticSurrogate
类,在其中为我们需要访问的静态属性创建实例属性:-
public class StaticSurrogate
{
public DateTime Today { get { return DateTime.Today; } }
public DateTime Now { get { return DateTime.Now; } }
}
现在我们需要一种格式化日期时间的方法。价值转换器是这项工作的正确工具,大量借鉴了Tim Heuer 博客:-
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();
}
}
有了这两个类,我们现在可以在 Xaml 中完成其余的工作,首先我们需要资源中这些类的实例:-
<UserControl.Resources>
<local:StaticSurrogate x:Key="Static" />
<local:FormatConverter x:Key="Formatter" />
</UserControl.Resources>
现在我们可以连接TextBlock
:-
<TextBlock Text="{Binding Today, Source={StaticResource Static},
Converter={StaticResource Formatter}, ConverterParameter='dd MMM yyy'}" />
请注意,这种方法具有以下优点:-
StaticSurrogate
类中。即使您可以在 Silverlight 的 XAML 中声明 DateTime.Now(因为您可以在 WPF - http://soumya.wordpress.com/2010/02/12/wpf-simplified-part-11-xaml-tricks/中),您也有你的时间不会更新的问题。如果您使用秒更新的本地计时器,您可以确保您的时间也会更新。
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
}
在 xaml ala 中声明 this 的一个实例:
<local:LocalTimer x:Key="theTime" Enabled="True" />
并使用绑定来确保始终反映您的时间。
<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" />
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Text="{Binding Source={x:Static sys:DateTime.Today}, StringFormat='Today is {0:dddd, MMMM dd}'}"