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
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" />
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:-
Hence we can analyse that we need two things.
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:-
StaticSurrogate
class.xmlns:sys="clr-namespace:System;assembly=mscorlib"
Text="{Binding Source={x:Static sys:DateTime.Today}, StringFormat='Today is {0:ffffdd, MMMM dd}'}"