использование логического преобразователя цвета в XAML - PullRequest
27 голосов
/ 16 декабря 2011

Я работаю над приложением WPF. Я привязал свой текстовый блок к своей кнопке. Я хочу установить передний план моего текстового блока в черный цвет, когда isEnabled соответствующей кнопки имеет значение true. Я хочу сделать это с помощью конвертера. Но это не работает . также не дает никакой ошибки. Я объявил следующий класс в своей папке "Модели".

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

Включение кнопки, свойство isable изменяется с viewmodel (например, с использованием RaiseCanExecuteChanged) ())

Связанные с текстовым блоком вещи в XAML:

   <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"/>

Ответы [ 3 ]

41 голосов
/ 16 декабря 2011

использовать return new SolidColorBrush (Colors.Black);

16 голосов
/ 16 декабря 2011

Ответ выше показывает, как правильно использовать конвертер.Тем не менее, вам действительно нужно использовать конвертер?Это можно сделать только в XAML, используя 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>

В приведенном выше примере первый TextBlock связывается с родительским IsEnabled свойство использует DataTrigger и устанавливает Foreground в некоторый цвет, если оно истинно.

Однако это излишне - свойство IsEnabled автоматически передается дочерним элементам WPF.То есть, если вы установите для IsEnabled значение false в своем Button, то для вашего TextBlock свойство IsEnabled будет автоматически обновлено до false.Это продемонстрировано во втором TextBlock, который использует свойство Trigger для проверки своего собственного свойства IsEnabled на значение true (так как его свойство IsEnabled будет таким же, как и у его родителя).Это был бы предпочтительный подход.

Надеюсь, это поможет!

6 голосов
/ 11 сентября 2015

Чтобы сделать этот конвертер общим, вы можете использовать ConverterParameter для указания цветов, которые должны быть вставлены, когда value имеет значение true или false.Также непрозрачность может представлять интерес.Здесь я предоставляю конвертер, который принимает параметр [ColorNameIfTrue; ColorNameIfFalse; OpacityNumber].

Поскольку метод SolidColorBrush(), упомянутый @ user1101511, является частью библиотеки System.Windows.Media, он использует тип Color из той же библиотеки.Этот тип не имеет метода Color.FromName(), как класс System.Drawing.Color.

Поэтому я создал вспомогательный метод под названием ColorFromName(string name).Я указываю "LimeGreen" в качестве запасного цвета, если интерпретация ConverterParameter не удалась.В моем случае я хочу, чтобы на выходе было "Transparent", когда value ложно.

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

Из xaml приведенный выше преобразователь может использоваться следующим образом:

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