Silverlight XAML TextBlock中的当前日期

时间:2010-03-12 05:22:05

标签: silverlight xaml date binding textblock

我来自Flex,您可以在花括号内做任何事情。我试图让TextBlock显示今天的日期和时间而不用在C#中编码。我尝试了以下许多不同的变化而没有运气。

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

我知道我可能只是设置一个属性MyDate并绑定到那个,但为什么我不能直接绑定到DateTime.Now属性?

3 个答案:

答案 0 :(得分:14)

Silverlight中的绑定需要Source对象或Dependency对象。从该源对象可以绑定到Properties(因此根据定义,您绑定到实例成员)或依赖属性。

由于DateTime.Now是静态属性,因此无法直接在Silverlight中绑定它,因此需要一些代码。接下来最好的事情是使用代码: -

  • 确保您需要的内容可以用XAML表示
  • 以尽可能脱离的方式这样做。

因此我们可以分析我们需要两件事。

  1. 将DateTime的静态成员公开为某个对象的实例属性
  2. 有一些方法可以将DateTime格式化为理想的输出。
  3. 要处理第一项,我将创建一个StaticSurrogate类,在那里我将为我们需要访问的静态属性创建实例属性: -

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

    现在我们需要一种格式化日期时间的方法。价值转换器是这项工作的正确工具,大量借鉴了这个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();
        }
    }
    

    有了这两个类,我们现在可以在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'}" />
    

    请注意,此方法具有以下优点: -

    • 我们不需要向放置TextBlock的UserControl添加代码,也不需要摆弄任何数据上下文。
    • 可以将静态资源放置在App.Resources中,这将使TextBlock的创建完全独立于必须向UserControl添加任何其他内容。
    • 用于显示日期的格式可以单独修改。
    • 可以轻松地将对其他静态属性的访问添加到StaticSurrogate类。

答案 1 :(得分:7)

即使您可以在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中声明一个这样的实例:

<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" />

答案 2 :(得分:1)

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

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