2010-03-12 11 views
8

Ich komme aus Flex, wo Sie fast alles innerhalb von geschweiften Klammern tun können. Ich versuche, eine TextBlock zu erhalten, um das heutige Datum und die heutige Zeit anzuzeigen, ohne es nur in C# zu codieren. Ich habe viele verschiedene Varianten der folgenden ohne Glück versucht.Aktuelles Datum in Silverlight XAML TextBlock

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

Ich weiß, ich könnte wahrscheinlich setzen nur eine Eigenschaft MyDate und binden sich an das, aber warum kann ich nicht binden direkt an die DateTime.Now Eigenschaft?

Antwort

14

Die Bindung in Silverlight erfordert ein Source-Objekt oder ein Dependency-Objekt. Von diesem Quellobjekt können Sie an Eigenschaften binden (daher sind Sie per Definition an Instanzmitglieder gebunden) oder an Abhängigkeitseigenschaften.

Da DateTime.Now eine statische Eigenschaft ist, können Sie nicht direkt in Silverlight an sie binden, daher wird Code benötigt. Die nächste beste Sache ist, den Code zu verwenden, um: -

  • sicherzustellen, so viel von dem, was Sie benötigen, können in XAML
  • ausgedrückt werden so in einer als entkoppelten Weise wie möglich zu tun.

Daher können wir analysieren, dass wir zwei Dinge brauchen.

  1. Expose die statischen Elemente der Datumzeit als Beispiel Eigenschaften eines Objekts
  2. irgendeine Weise die Datumzeit auf eine gewünschte Ausgabe zu formatieren.

Um den ersten Punkt behandeln würde ich erstellen StaticSurrogate Klasse, wo ich Instanzeigenschaften für die statischen Eigenschaften führen würde, dass wir Zugang müssen: -

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

Jetzt müssen wir einen Weg ein zu formatieren Terminzeit. Ein Wertwandler ist das richtige Werkzeug für diesen Job, Kreditaufnahme stark von dieser 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(); 
    } 
} 

Mit diesen beiden Klassen an Ort und Stelle können wir jetzt tun, den Rest in XAML, zuerst müssen wir Instanzen dieser Klassen in unserer Ressourcen : -:

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

Beachten Sie, dass dieser Ansatz hat folgende Vorteile: - -

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

Jetzt können wir die TextBlock verdrahten

  • Wir müssen dem UserControl, auf dem der TextBlock platziert ist, keinen Code hinzufügen, und wir müssen auch nicht mit irgendeinem Datenkontext herumspielen.
  • Die statischen Ressourcen können in App.Resources platziert werden, wodurch die Erstellung des TextBlocks völlig unabhängig von der Notwendigkeit ist, dem Benutzersteuerelement weitere Elemente hinzuzufügen.
  • Die Formatierung zur Anzeige des Datums kann unabhängig voneinander geändert werden.
  • Der Zugriff auf zusätzliche statische Eigenschaften kann problemlos zur Klasse StaticSurrogate hinzugefügt werden.
  • +0

    Das macht Sinn für mich, aber es ist extrem scheint im Vergleich zu der Flex-Syntax: text = "{new Date()}". Ich denke, das alles läuft darauf hinaus, dass Silverlight nur einige Markup-Erweiterungen in XAML unterstützt. Es wäre schön, wenn sie die Bewertung der geschweiften Klammer robuster machen würden. Danke für Ihre Hilfe! –

    7

    Selbst wenn Sie DateTime.Now in XAML von Silverlight deklarieren könnten (da Sie in WPF - http://soumya.wordpress.com/2010/02/12/wpf-simplified-part-11-xaml-tricks/ können), haben Sie das Problem, dass Ihre Zeit nicht aktualisiert wird. Wenn Sie einen lokalen Timer verwenden, der auf der Sekunde aktualisiert, können Sie sicherstellen, dass Ihre Zeit auch aktualisiert wird.

    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 
    } 
    

    eine Instanz dies in XAML ala erklären:

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

    und die Bindung verwenden, um sicherzustellen, dass Ihre Zeit immer widerspiegelt.

    <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

    Ist dies die beste Vorgehensweise, oder gibt es eine elegantere Art, Aktualisierungen vorzunehmen? – fzl

    1
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    
    Text="{Binding Source={x:Static sys:DateTime.Today}, StringFormat='Today is {0:dddd, MMMM dd}'}" 
    
    +0

    Kann dies nicht direkt in Silverlight tun, siehe http://stackoverflow.com/questions/3373926/silverlight-4-equivalent-to-wpf-xstatic – davidsleeps

    +0

    Das ist der Grund, warum WPF großartig ist. –