2011-12-16 10 views
22

Estoy trabajando en la aplicación WPF. He vinculado mi bloque de texto a mi botón. Quiero establecer el primer plano de mi bloque de texto en color negro cuando el botón asociado isEnabled es verdadero. Quiero hacer esto usando el convertidor. Pero no está funcionando. también no dando ningún error. He declarado la siguiente clase en mi carpeta "Modelos".uso del convertidor booleano a color en XAML

public class BrushColorConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if ((bool)value) 
     { 
      { 
       return System.Windows.Media.Colors.Black; 
      } 
     } 
     return System.Windows.Media.Colors.LightGreen; 
    } 

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

botón de habilitación, cambios de propiedad ESACTIVE de modelo de vista (por ejemplo, utilizando RaiseCanExecuteChanged)())

cosas relacionadas textblock en XAML son:

<Window.Resources> 
      <local:BrushColorConverter x:Key="BConverter"></local:BrushColorConverter> 
    </Window.Resources> 
<Button>(!..all button properties..!)</Button> 
    <TextBlock x:Name="AnswerText"           
       Text="Answer"           
       Foreground="{Binding ElementName=AnswerButton,Path=IsEnabled, Converter={StaticResource BConverter}}" 
       TextWrapping="Wrap"/> 
+0

probar regresar de cadena: 'System.Windows.Media.Colors.Black.ToString() ' – sll

+0

Bingo ... eso es genial. Gracias. – deathrace

Respuesta

33

uso volver nueva SolidColorBrush (Colores .Negro);

+0

Gracias. eso es más preciso, ya que puedo devolver el color directamente en lugar de devolver 'cadena'. – deathrace

13

La respuesta anterior muestra cómo usar correctamente un convertidor. Sin embargo, ¿realmente necesitas usar un convertidor? Esto se puede hacer en XAML utilizando sólo Triggers:

XAML

 <StackPanel> 

      <Button IsEnabled="{Binding ElementName=isEnabledCheckBox, Path=IsChecked}"> 
       <TextBlock Text="Answer" TextWrapping="Wrap"> 
        <TextBlock.Style> 
         <Style TargetType="{x:Type TextBlock}"> 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsEnabled}" Value="True"> 
            <Setter Property="Foreground" Value="Green"/> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </TextBlock.Style> 
       </TextBlock> 
      </Button> 

      <Button IsEnabled="{Binding ElementName=isEnabledCheckBox, Path=IsChecked}"> 
       <TextBlock Text="Answer" TextWrapping="Wrap"> 
        <TextBlock.Style> 
         <Style TargetType="{x:Type TextBlock}"> 
          <Style.Triggers> 
           <Trigger Property="IsEnabled" Value="True"> 
            <Setter Property="Foreground" Value="Green"/> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </TextBlock.Style> 
       </TextBlock> 
      </Button> 

      <CheckBox x:Name="isEnabledCheckBox" Content="Toggle IsEnable on Buttons above" /> 

     </StackPanel> 

En el ejemplo anterior, la primera TextBlock se une a IsEnabled la propiedad de su padre utilizando una DataTrigger, y establece el Foreground a poco de color si es verdad.

Sin embargo, esto es exagerado: la propiedad IsEnabled se propaga automáticamente a los niños por WPF. Es decir, si configura IsEnabled como falso en su Button, su TextBlock tendrá su propiedad IsEnabled actualizada automáticamente en falso. Esto se demuestra en el segundo TextBlock que usa una propiedad Trigger para verificar su propia propiedad IsEnabled contra el valor de verdadero (ya que su propiedad IsEnabled será la misma que la de su padre). Este sería el enfoque preferido.

Espero que esto ayude!

+0

esto también es un gran trabajo. Intenté lo mismo antes, pero no pude vincularme con sus padres. Pero relativesource resolverá ese problema. Gracias. – deathrace

4

Para hacer que este convertidor sea general, puede usar un ConverterParameter para especificar los colores que se van a insertar cuando value es verdadero o falso. También la opacidad puede ser de interés. Aquí proporciono el convertidor que toma el parámetro [ColorNameIfTrue; ColorNameIfFalse; OpacityNumber].

Dado que el método SolidColorBrush() mencionado por @ user1101511 es parte de la biblioteca System.Windows.Media, se utiliza el tipo de esa misma biblioteca Color. Este tipo no tiene un método Color.FromName(), como la clase System.Drawing.Color.

Therfore Hice un método de ayuda llamado ColorFromName(string name). Especifico "LimeGreen" como un color de reserva si la interacción de ConverterParameter falla. En mi caso, quiero que la salida sea "Transparent" cuando value es falso.

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

namespace MyConverters 
{ 
    [ValueConversion(typeof(bool), typeof(SolidColorBrush))] 
    class BoolToColorBrushConverter : IValueConverter 
    { 
     #region Implementation of IValueConverter 

     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="value">Bolean value controlling wether to apply color change</param> 
     /// <param name="targetType"></param> 
     /// <param name="parameter">A CSV string on the format [ColorNameIfTrue;ColorNameIfFalse;OpacityNumber] may be provided for customization, default is [LimeGreen;Transperent;1.0].</param> 
     /// <param name="culture"></param> 
     /// <returns>A SolidColorBrush in the supplied or default colors depending on the state of value.</returns> 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     SolidColorBrush color; 
     // Setting default values 
     var colorIfTrue = Colors.LimeGreen; 
     var colorIfFalse = Colors.Transparent; 
     double opacity = 1; 
     // Parsing converter parameter 
     if (parameter != null) 
     { 
      // Parameter format: [ColorNameIfTrue;ColorNameIfFalse;OpacityNumber] 
      var parameterstring = parameter.ToString(); 
      if (!string.IsNullOrEmpty(parameterstring)) 
      { 
       var parameters = parameterstring.Split(';'); 
       var count = parameters.Length; 
       if (count > 0 && !string.IsNullOrEmpty(parameters[0])) 
       { 
        colorIfTrue = ColorFromName(parameters[0]); 
       } 
       if (count > 1 && !string.IsNullOrEmpty(parameters[1])) 
       { 
        colorIfFalse = ColorFromName(parameters[1]); 
       } 
       if (count > 2 && !string.IsNullOrEmpty(parameters[2])) 
       { 
        double dblTemp; 
        if (double.TryParse(parameters[2], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture.NumberFormat, out dblTemp)) 
         opacity = dblTemp; 
       } 
      } 
     } 
     // Creating Color Brush 
     if ((bool) value) 
     { 
      color = new SolidColorBrush(colorIfTrue); 
      color.Opacity = opacity; 
     } 
     else 
     { 
      color = new SolidColorBrush(colorIfFalse); 
      color.Opacity = opacity; 
     } 
     return color; 
    } 


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

    #endregion 

    public static Color ColorFromName(string colorName) 
    { 
     System.Drawing.Color systemColor = System.Drawing.Color.FromName(colorName); 
     return Color.FromArgb(systemColor.A, systemColor.R, systemColor.G, systemColor.B); 
    } 
} 

De xaml el convertidor anteriormente se pueden usar como esto:

Background="{Binding MyBooleanValue, Converter={StaticResource BoolToColorBrushConverter}, ConverterParameter=LimeGreen;Transperent;0.2, Mode=OneWay}" 
Cuestiones relacionadas