Подтвердить что ты не робот

Использование булевых в цветной конвертер в XAML

Я работаю над приложением 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"/>
4b9b3361

Ответ 1

использование вернуть новый SolidColorBrush (Colors.Black);

Ответ 2

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

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

Ответ 3

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

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

Поэтому я сделал вспомогательный метод под названием ColorFromName(string name). Я указываю "LimeGreen" как резервный цвет, если интерпретация ConverterParameter не выполняется. В моем случае я хочу, чтобы результат был "Transparent", когда value имеет значение 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);
    }
}

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

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