2010-07-08 11 views
8

Estoy tratando de encontrar la mejor manera de crear un estilo/activador para establecer el primer plano en rojo, cuando el valor es < 0. ¿cuál es la mejor manera de hacerlo? Asumo DataTrigger, pero ¿cómo puedo verificar el valor negativo? ¿Tengo que crear mi propio IValueConverter?Número negativo WPF TextBlock en rojo

Respuesta

14

Si no está utilizando un modelo MVVM (donde puede tener una propiedad ForegroundColor), entonces lo más fácil es crear un nuevo IValueConverter, vinculando su fondo a su valor.

En MyWindow.xaml:

<Window ... 
    xmlns:local="clr-namespace:MyLocalNamespace"> 
    <Window.Resources> 
     <local:ValueToForegroundColorConverter x:Key="valueToForeground" /> 
    <Window.Resources> 

    <TextBlock Text="{Binding MyValue}" 
       Foreground="{Binding MyValue, Converter={StaticResource valueToForeground}}" /> 
</Window> 

ValueToForegroundColorConverter.cs

using System; 
using System.Windows.Media; 
using System.Windows.Data; 

namespace MyLocalNamespace 
{ 
    class ValueToForegroundColorConverter: IValueConverter 
    { 
     #region IValueConverter Members 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      SolidColorBrush brush = new SolidColorBrush(Colors.Black); 

      Double doubleValue = 0.0; 
      Double.TryParse(value.ToString(), out doubleValue); 

      if (doubleValue < 0) 
       brush = new SolidColorBrush(Colors.Red); 

      return brush; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 
} 
+0

esto funcionaría , aunque preferiría crear algún tipo de estilo (más fácil de reimplementar), ¿por qué no funciona con MVVM? –

+2

@LnDCobra: Funcionará con MVVM. Lo que creo que Wonko significa es que con MVVM puede elegir exponer una propiedad de ForegroundColor en su viewmodel en lugar de usar un ValueConverter. –

+1

@Jakob: absolutamente correcto. @LnDCobra: podría implementar un estilo, con el valor de la propiedad de primer plano establecido en el mismo enlace que el anterior.

8

Usted debe tener su información específica vista en su modelo de vista. Pero puede deshacerse de la información específica de Style en ViewModel.

Por lo tanto crear una propiedad en el modelo de vista que devolver un valor bool

public bool IsMyValueNegative { get { return (MyValue < 0); } } 

y utilizarlo en un DataTrigger para que pueda eliminar la ValueConverter y su boxeo/unboxing.

<TextBlock Text="{Binding MyValue}"> 
    <TextBlock.Style> 
    <Style> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding IsMyValueNegative}" Value="True"> 
      <Setter Property="Foreground" Value="Red" /> 
     </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    </TextBlock.Style> 
</TextBlock> 
+0

Acordó que esto sería preferible. La respuesta original proviene del hecho de que él no mencionó que estaba usando MVVM, y la pregunta implicó (para mí) que no era así. –

+0

Esto funcionaría, pero la razón por la que no quiero hacer esto es porque por cada TextBlock necesitaría una propiedad separada para cada bloque de texto (más de 10 por vista) –

+0

Solo un pequeño punto sobre convenciones de nombres ... Mis aplicaciones estar tan lleno de este tipo de hack xaml que me parece más fácil nombrarlos por su propósito. es decir: public bool DisplayBasketValueInRed {get; conjunto; }. También utilizo (aunque probablemente no) una clase genérica para reducir la forma detallada en que se puede implementar INotifyPropertyChanged en estas propiedades. –

4

Para la solución de Amsakanna he tenido que añadir un nombre de clase a la Setter propiedad:

< Setter propiedad = "TextBlock .Foreground" Value = "Red" />

+0

¡yo también !. ¡Gracias! – tzippy