2011-12-16 6 views
22

Sto lavorando su WPF application.I hanno legato il mio blocco di testo al mio pulsante. Voglio impostare il primo piano del mio blocco di testo su un colore nero quando isEnabled del pulsante associato è vero. Voglio farlo usando il convertitore. Ma non funziona. anche senza dare alcun errore. Ho dichiarato la seguente classe nella mia cartella "Models".uso di booleana per Color Converter in 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(); 
    } 
} 

Pulsante di abilitazione, modifiche alle proprietà Isable da viewmodel (ad esempio utilizzando RaiseCanExecuteChanged)())

cose legate TextBlock in XAML sono:

<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

provare tornare stringa: 'System.Windows.Media.Colors.Black.ToString() ' – sll

+0

Bingo .. è fantastico. Grazie. – deathrace

risposta

33

uso tornare nuova SolidColorBrush (colori .Nero);

+0

Grazie. questo è più preciso, dal momento che sono in grado di restituire il colore direttamente invece di restituire 'stringa'. – deathrace

13

La risposta di cui sopra mostra come correttamente si utilizza per un convertitore. Tuttavia, hai davvero bisogno di usare un convertitore? Questo può essere fatto in XAML utilizzando solo 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> 

Nell'esempio di cui sopra, il primo TextBlock si lega alla proprietà del suo genitore IsEnabled utilizzando un DataTrigger, e imposta la Foreground per un pò di colore se è vero.

Tuttavia, questo è eccessivo - la proprietà IsEnabled si propaga verso il basso per i bambini automaticamente dal WPF. Cioè, se si imposta IsEnabled false sul tuo Button, allora il vostro TextBlock avrà la sua proprietà IsEnabled aggiornato su false automaticamente. Questo è dimostrato nella seconda TextBlock che utilizza una proprietà Trigger per controllare il proprio IsEnabled proprietà contro il valore della vera (in quanto la sua proprietà IsEnabled sarà lo stesso del suo genitore). Questo sarebbe l'approccio preferito.

Spero che questo aiuti!

+0

anche questo è un ottimo lavoro. Ho provato lo stesso prima, ma non ero in grado di legare ai suoi genitori. Ma parentsource risolverà questo problema. Grazie. – deathrace

4

Per rendere questo convertitore generale è possibile utilizzare uno ConverterParameter per specificare i colori da inserire quando value è vero o falso. Anche l'opacità potrebbe essere di interesse. Qui fornisco al convertitore I il parametro [ColorNameIfTrue; ColorNameIfFalse; OpacityNumber].

Poiché il metodo SolidColorBrush() menzionato da @user1101511 fa parte della libreria System.Windows.Media, utilizza il tipo dalla stessa libreria. Questo tipo non ha un metodo Color.FromName(), come la classe System.Drawing.Color.

Therfore Ho fatto un metodo di supporto chiamato ColorFromName(string name). Specifico "LimeGreen" come colore di fallback se l'interpertazione di ConverterParameter fallisce. Nel mio caso voglio che l'output sia "Transparent" quando value è 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); 
    } 
} 

Da XAML il convertitore di cui sopra può essere utilizzato in questo modo:

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