2010-03-12 10 views
8

Vengo de Flex, donde puedes hacer casi cualquier cosa dentro de las llaves. Estoy tratando de obtener un TextBlock para mostrar la fecha y la hora de hoy sin solo codificarlo en C#. He intentado muchas variaciones diferentes de lo siguiente sin suerte.Fecha actual en Silverlight XAML TextBlock

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

Sé que podría probablemente sólo establecer una propiedad MyDate y se unen a eso, pero ¿por qué no puedo enlazar directamente a la propiedad DateTime.Now?

Respuesta

14

Encuadernación en Silverlight requiere un objeto Fuente o un objeto Dependencia. Desde ese objeto de origen puede vincularse a Propiedades (por lo tanto, por definición, está vinculando a miembros de instancia) o Propiedades de Dependencia.

Dado que DateTime.Now es una propiedad estática, no se puede enlazar directamente en Silverlight, por lo tanto, se necesita un código. La segunda mejor opción es utilizar código para: -

  • garantizar que gran parte de lo que necesita puede ser expresado en XAML
  • para hacerlo de una manera tan disociado de lo posible.

Por lo tanto, podemos analizar que necesitamos dos cosas.

  1. Exponer los miembros estáticos de DateTime como propiedades de la instancia de un objeto
  2. tener alguna forma para formatear la DateTime a una salida deseable.

para manejar el primer punto me gustaría crear una clase StaticSurrogate, donde me gustaría crear propiedades de instancia para las propiedades estáticas que tenemos acceso a: -

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

Ahora necesitamos una manera de formatear una Fecha y hora. Un convertidor de valores es la herramienta adecuada para este trabajo, préstamos en gran medida de esta 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(); 
    } 
} 

Con estas dos clases en el lugar que ahora podemos hacer el resto en XAML, primero necesitamos instancias de estas clases en nuestros recursos : -

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

Ahora podemos cablear el TextBlock: - Nota

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

que este enfoque tiene las siguientes ventajas: -

  • no es necesario que agreguemos código al UserControl en el que se coloca TextBlock, ni tenemos que jugar con ningún contexto de datos.
  • Los recursos estáticos podrían colocarse en la aplicación. Recursos que harían que la creación de TextBlock fuera completamente independiente de tener que agregar algo más al UserControl.
  • El formato utilizado para mostrar la fecha se puede modificar independientemente.
  • El acceso a propiedades estáticas adicionales se puede agregar fácilmente a la clase StaticSurrogate.
+0

que tenga sentido para mí, pero sí parece extrema en comparación con la sintaxis Flex: text = "{new Date()}". Supongo que todo esto se reduce al hecho de que Silverlight solo admite algunas extensiones de marcado dentro de XAML. Sin embargo, estaría bien si hicieran más robustas las evaluaciones de corsé. ¡Gracias por tu ayuda! –

7

Incluso si se pudiera declarar DateTime.Now en XAML de Silverlight (ya que se puede en WPF - http://soumya.wordpress.com/2010/02/12/wpf-simplified-part-11-xaml-tricks/), tiene el problema de que su tiempo no se actualizará. Si usa un temporizador local que se actualiza el segundo, puede asegurarse de que su tiempo también se actualice.

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 
} 

Declare una instancia de este en el ala xaml:

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

y utilice la unión para asegurar que su tiempo siempre se refleja.

<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

¿Es esta la mejor práctica, o hay una forma más elegante de hacer las actualizaciones? – 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

No se puede hacer esto directamente en Silverlight, see- http://stackoverflow.com/questions/3373926/silverlight-4-equivalent-to-wpf-xstatic – davidsleeps

+0

Es por eso que WPF es increíble. –

Cuestiones relacionadas