Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use of boolean to color converter in XAML

use return new SolidColorBrush(Colors.Black);


The answer above shows you how to correctly you use a converter. However, do you really need to use a converter? This can be done in XAML only using 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>

In the example above, the first TextBlock binds to its parent's IsEnabled property using a DataTrigger, and sets the Foreground to some colour if it is true.

However, this is overkill - the IsEnabled property is propagated down to children automatically by WPF. That is, if you set IsEnabled to false on your Button, then your TextBlock will have its IsEnabled property updated to false automatically. This is demonstrated in the second TextBlock which uses a property Trigger to check its own IsEnabled property against the value of true (since its IsEnabled property will be the same as its parent's). This would be the preferred approach.

Hope this helps!


To make this converter general you may use a ConverterParameter for specifying the colors which is to be inserted when value is true or false. Also the opacity may be of interest. I here provide the Converter I taking the parameter [ColorNameIfTrue;ColorNameIfFalse;OpacityNumber].

Since the SolidColorBrush() method mentioned by @user1101511 is part of the System.Windows.Media library, it uses the Color type from that same library. This type does not have a Color.FromName() method, like the System.Drawing.Color class.

Therfore I made a helper method called ColorFromName(string name). I specify "LimeGreen" as a fallback color if the interpertation of ConverterParameter fails. In my case I want the output to be "Transparent" when value is false.

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);
    }
}

From xaml the above converter may be used like this:

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