2010-06-24 14 views
5

Quiero comparar dos versiones de varias propiedades y marcar una de ellas en negrita si no es igual a la otra. Como SL4 no es compatible con MultiBinding, estoy vinculando FontWeight a "." para que todo el contexto de datos se pase al convertidor. Luego uso el parámetro del convertidor para especificar qué campos comparar dentro del convertidor. Hasta ahora, muy bien ... Los valores que no coinciden son en negrita.Encuadernación a FontWeight en Silverlight 4 usando un convertidor de valor

El problema es que la propiedad en negrita está vinculada a un cuadro de texto que se puede editar. Cuando se edita el valor, quiero que el convertidor se "vuelva a activar" para que el peso de la fuente se establezca de acuerdo con el nuevo valor. Esto no sucede. ¿Cómo se puede lograr esto?

Nota: Ya he implementado INotifyPropertyChanged para la clase y las propiedades relevantes. Al marcar el siguiente campo después de cambiar el valor, se activa el evento PropertyChanged, pero el peso de la fuente no se actualiza hasta que realmente me muevo a un registro diferente y luego vuelvo al registro que se cambió.

(también probé con el Modo = TwoWay para ver si eso fuera a hacer el truco. Sin embargo, TwoWay vinculante no se puede utilizar cuando desee realizar la vinculación "")

Respuesta

2

¿Necesita utilizar un convertidor de valores? Intenté esto rápido usando el patrón MVVM y funcionó bastante bien. Si se pudiera usar MVVM, que posiblemente podría hacerlo de esta manera:

MainPage.xaml

<UserControl x:Class="BindBoldText.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:local="clr-namespace:BindBoldText" 
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="400"> 

<UserControl.DataContext> 
    <local:MainPage_ViewModel/> 
</UserControl.DataContext> 

<StackPanel> 
    <TextBlock Text="{Binding Value1, Mode=TwoWay}"/> 
    <TextBlock Text="{Binding Value2, Mode=TwoWay}" FontWeight="{Binding Value2FontWeight}"/> 
    <TextBox Text="{Binding Value2, Mode=TwoWay}" TextChanged="TextBox_TextChanged"/> 
</StackPanel> 

MainPage.xaml.cs

public partial class MainPage : UserControl 
{ 
    public MainPage() 
    { 
     InitializeComponent(); 

     this.viewModel = this.DataContext as MainPage_ViewModel; 
    } 

    private MainPage_ViewModel viewModel; 

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
    {    
     viewModel.Value2 = (sender as TextBox).Text; 
    } 
} 

MainPage_ViewModel.cs

public class MainPage_ViewModel : INotifyPropertyChanged 
{ 
    public string Value1 
    { 
     get { return value1; } 
     set 
     { 
      if (value1 != value) 
      { 
       value1 = value; 
       OnPropertyChanged("Value1"); 
      } 
     } 
    } 
    private string value1 = "Test"; 

    public string Value2 
    { 
     get { return value2; } 
     set 
     { 
      if (value2 != value) 
      { 
       value2 = value; 
       OnPropertyChanged("Value2"); 
       OnPropertyChanged("Value2FontWeight"); 
      } 
     } 
    } 
    private string value2 = "Test"; 

    public FontWeight Value2FontWeight 
    { 
     get 
     { 
      if (value2.Equals(value1)) 
      { 
       return FontWeights.Normal; 
      } 
      else 
      { 
       return FontWeights.Bold; 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 
} 
+0

Gracias por su respuesta. (Perdón por el retraso. Acabo de volver de unas vacaciones cortas, pero muy necesarias. :-)) Voy a probar este enfoque junto con la sugerencia de GreenIcicle a continuación. No es un requisito hacer esto en un convertidor de valor. Sin embargo, estoy tratando de hacer esto en conjunto con los Servicios de RIA. ¿Hay alguna advertencia que deba tener en cuenta cuando utilice un enfoque de MVVM como lo describe arriba junto con los Servicios de RIA? – MylesRip

+0

Probé esto y funcionó para mí. FWIW ... En RIA Services puedo usar el código .shared para agregar la propiedad "Value2FontWeight" (como se define arriba) a mi DTO (en cuyo caso supongo que ya no es un DTO en el sentido más estricto, pero está bien) – MylesRip

+1

FWIW ... Parece que hay un pequeño problema al usar este enfoque con los Servicios RIA (si no está usando un modelo de vista, eso es).El código que se genera para el cliente proporciona sus propios métodos de configuración para las propiedades, por lo que la llamada a OnPropertyChanged ("Value2FontWeight") en la solución anterior nunca se ejecuta porque no existe en el generador creado. – MylesRip

0

En su solución, el valor no se actualiza porque la propiedad en sí está vinculada al contexto de datos completo a través del "." expresión. Se puede invocar INotifyPropertyChanged, pero este evento significa que una sola propiedad ha cambiado, y dado que no proporciona un nombre de propiedad en la expresión de enlace, el sistema de enlace de datos no sabe que la vinculación necesita actualizarse; no puede mira qué hace tu convertidor de valor.

Creo que el applet de JSprang es mucho mejor, al menos porque proporciona una mejor separación de la lógica de presentación que puede probarse a partir del marcado. Para ir más allá con una interfaz limpia, podría dejar que ViewModel implemente una propiedad booleana "ValuesAreSame", enlazar datos con ella y usar un convertidor de valor para aplicar el estilo visual real (en este caso, un peso de fuente).

+0

Gracias por la entrada. El enfoque de JSprang resolvió el problema y me gusta su sugerencia de mantener limpia la interfaz al separar la evaluación de la condición de la que está indicada en la IU. – MylesRip

Cuestiones relacionadas