Текущая дата в Silverlight XAML TextBlock

Я происхожу из Flex, где можно сделать примерно что-либо в фигурных скобках. Я пытаюсь получить a TextBlock отобразить сегодняшнюю Дату и время, просто не кодируя его в C#. Я попробовал много различных изменений следующего без удачи.

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

Я знаю, что мог, вероятно, просто установить свойство MyDate и свяжите с этим, но почему я не могу связать непосредственно с DateTime.Now свойство?

8
задан sth 13 May 2011 в 11:32
поделиться

2 ответа

Для привязки в Silverlight требуется объект Source или объект Dependency. Из этого исходного объекта вы можете выполнить привязку к свойствам (следовательно, по определению вы привязываетесь к членам экземпляра) или к свойствам зависимостей.

Поскольку DateTime.Now является статическим свойством, вы не можете напрямую привязать его к Silverlight, поэтому требуется некоторый код. Следующим лучшим вариантом является использование кода для: -

  • обеспечения того, чтобы как можно больше из того, что вам нужно, можно было выразить в XAML
  • , чтобы сделать это как можно более изолированным способом.

Следовательно, мы можем проанализировать, что нам нужны две вещи.

  1. Предоставьте статические члены DateTime как свойства экземпляра некоторого объекта
  2. Найдите способ отформатировать DateTime для получения желаемого результата.

Для обработки первого элемента я бы создал класс 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'}" />

Обратите внимание, что этот подход имеет следующие преимущества: -

  • нам не нужно добавлять код в UserControl на котором размещается TextBlock, и нам не нужно возиться с каким-либо контекстом данных.
  • Статические ресурсы могут быть размещены в App.Resources, что сделает создание TextBlock полностью независимым от необходимости добавлять что-либо еще в UserControl.
  • Форматирование, используемое для отображения даты, можно изменять независимо.
  • Доступ к дополнительным статическим свойствам можно легко добавить к классу StaticSurrogate .
14
ответ дан 5 December 2019 в 07:34
поделиться

Даже если бы вы могли объявить 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" />
7
ответ дан 5 December 2019 в 07:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: