Current Date in Silverlight XAML TextBlock

后端 未结 3 549
暗喜
暗喜 2021-02-09 02:17

I am coming from Flex where you can do just about anything inside of curly braces. I am trying to get a TextBlock to display today\'s Date and Time without just cod

相关标签:
3条回答
  • 2021-02-09 02:33

    Even if you could declare DateTime.Now in Silverlight's XAML (since you can in WPF - http://soumya.wordpress.com/2010/02/12/wpf-simplified-part-11-xaml-tricks/), you have the issue that your time won't update. If you use a local timer that updates on the second you can ensure that your time will update as well.

    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 = "ffffdd, 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
    }
    

    Declare an instance of this in xaml ala:

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

    and use the binding to ensure that your time is always reflected.

    <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 讨论(0)
  • 2021-02-09 02:45

    Binding in Silverlight requires a Source object or a Dependency object. From that source object you can bind to Properties (hence by definition you are binding to instance members) or Dependency Properties.

    Since DateTime.Now is a static property you cannot bind to it in Silverlight directly, hence some code is needed. The next best thing is to use code to:-

    • ensure as much of what you need can be expressed in XAML
    • to do so in an as de-coupled manner as possible.

    Hence we can analyse that we need two things.

    1. Expose the static members of DateTime as instance properties of some object
    2. Have some way to format the DateTime to a desirable output.

    To handle the first item I would create a StaticSurrogate class, where I would create instance properties for the static properties that we need access to:-

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

    Now we need a way to format a Date time. A value converter is the right tool for this job, borrowing heavily from this 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();
        }
    }
    

    With these two classes in place we can now do the rest in Xaml, first we need instances of these classes in our resources:-

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

    Now we can wire up the TextBlock :-

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

    Note that this approach has the following advantages:-

    • we do not need to add code to the UserControl on which the TextBlock is placed, nor do we have to fiddle around with any data context.
    • The Static resources could be placed in the App.Resources which would make the creation of the TextBlock entirely independent of having to add anything else to the UserControl.
    • The formatting used to display the date can be independently modified.
    • Access to additional static properties can easily be added to the StaticSurrogate class.
    0 讨论(0)
  • 2021-02-09 02:45
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    
    Text="{Binding Source={x:Static sys:DateTime.Today}, StringFormat='Today is {0:ffffdd, MMMM dd}'}"
    
    0 讨论(0)
提交回复
热议问题