Я происхожу из Flex, где можно сделать примерно что-либо в фигурных скобках. Я пытаюсь получить a 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; } }
}
Теперь нам нужен способ форматирования даты время.Преобразователь значений - правильный инструмент для этой работы, он в значительной степени заимствован из этого Блог Тима Хойера : -
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
. Даже если бы вы могли объявить DateTime.Now в XAML Silverlight (так как вы можете это сделать в 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" />