在XAML中使用布尔值到颜色转换器的方法

36

我正在开发一个WPF应用程序。我已经将我的文本框绑定到我的按钮上。当与它相关联的按钮isEnabled为true时,我想将文本块的前景设置为黑色。我想使用转换器来实现这一点。但是它不起作用,也没有出现任何错误。我在“Models”文件夹中声明了以下类。

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

йҖҡиҝҮViewModelжӣҙж”№жҢүй’®зҡ„Enableе’ҢDisableеұһжҖ§пјҲдҫӢеҰӮдҪҝз”ЁRaiseCanExecuteChangedпјү

XAMLдёӯдёҺTextBlockзӣёе…ізҡ„еҶ…е®№жңүпјҡ

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

尝试返回字符串:System.Windows.Media.Colors.Black.ToString() - sll
3个回答

57

use return new SolidColorBrush(Colors.Black);


谢谢。这更准确,因为我能够直接返回颜色,而不是返回“字符串”。 - deathrace

21
上面的回答展示了如何正确地使用转换器。然而,你真的需要使用转换器吗?这可以仅通过在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 使用 DataTrigger 绑定到其父级的 IsEnabled 属性,并在该属性为 true 时将 Foreground 设置为某种颜色。
然而,这样做有点过度 - WPF 会自动将 IsEnabled 属性传递给子元素。也就是说,如果你在你的 Button 上将 IsEnabled 设置为 false,则你的TextBlockIsEnabled 属性将自动更新为 false。这在第二个 TextBlock 中展示了出来,它使用一个 Trigger 属性来检查其自身的 IsEnabled 属性是否与 true 的值相同(因为它的 IsEnabled 属性与其父元素的相同)。这将是首选方法。
希望这可以帮助你!

这也是一项伟大的工作。我之前尝试过相同的操作,但无法绑定到其父级。但是相对源将解决这个问题。谢谢。 - deathrace
如果你正在使用类似于Material Design in XAML的东西,这个方法是行不通的,因为设置样式触发器会覆盖掉控件的整个材料设计风格。 - Good Night Nerd Pride

14

为了使这个转换器更通用,您可以使用 ConverterParameter 来指定当 value 为 true 或 false 时要插入的颜色,并且透明度可能也很重要。我在此提供带有参数 [ColorNameIfTrue;ColorNameIfFalse;OpacityNumber] 的 Converter。

由于 @user1101511 提到的 SolidColorBrush() 方法是 System.Windows.Media 库的一部分,因此它使用该库中的 Color 类型。这个类型没有像 System.Drawing.Color 类那样的 Color.FromName() 方法。

因此,我编写了一个帮助方法叫做 ColorFromName(string name)。如果解释 ConverterParameter 失败,我将指定 "LimeGreen" 作为备用颜色。在我的情况下,当 value 为 false 时,我想要输出 "Transparent"

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

最佳答案在这里! - szMuzzyA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接