如何在 wpf xaml 中使用值转换器的特定属性

How to use specific properties of a Value converter in wpf xaml

我有一个枚举到字符串的转换器

public class EnumToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        MailSettingsStateEnum enumValue = (MailSettingsStateEnum)value;

        // extension method on the enum, to return a string based on enum.
        return enumValue.Description(); 
    }

    // ConvertBack not relevant here.
}

我在 wpf xaml 中使用它很容易,如下所示设置标签的内容 属性。

<Label Content="{Binding MailSettingState, Converter={StaticResource 
EnumConverterString}}" 
BorderBrush="{Binding MailSettingState, Converter={StaticResource 
EnumConverterBorderBrush}}" />

现在如您所见,我还有另一个 属性 BorderBrush。我还必须基于相同的枚举来设置它。所以我不得不写另一个转换器 EnumConverterBorderBrush

那么有没有一种方法可以让我只有一个转换器,它 return 一个具有两个属性的对象,我可以在 xaml 中使用这些属性?我可以创建转换器,很简单,但我不知道如何在 xaml 中使用它。假设转换器 return 编辑了一个对象并且有两个 属性 称为 MessageString(字符串类型)和另一个 Brush 类型的 BorderBrush,我如何使用它 xaml?

您可以根据转换器中收到的 targetType 切换输出。

所以你可以这样做:

public class EnumToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        CultureInfo culture)
    {
        var enumValue = (MailSettingsStateEnum)value;

        switch(targetType)
        {
            case typeof(string)
                return enumValue.Description(); 
            case typeof(Brush)
                return enumValue.GetBrush();
            default:
                throw new NotSupportedException("Type not supported")
        }
    }

    // ConvertBack not relevant here.
}

现在您将拥有一个转换器来统领一切!

我已经在上面评论过,但这是解决方案。

<Label DataContext="{Binding MailSettingState, Converter={converters:EnumConverter}}" Content="{Binding Label}" BorderBrush="{Binding BorderBrush}"/>

public class EnumConverter: MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var enumValue = (MailSettingsStateEnum) value;
        return new ConvertedEnum { Label = enumValue.Description(), 
                                   BorderBrush = new BorderBrush()};

    }

    // ConvertBack not relevant here.

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
} 

public class ConvertedEnum
{
    public string Label {get; set;}
    public BorderBrush {get; set;}
}

单独的转换器在我看来仍然更漂亮。

转换器应该 return 匹配所请求的对象 targetType。转换器可以 return 不同的输入值 enum 值取决于 parameter。我认为它比仅依赖 targetType 更灵活。

public class SpecEnumConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Enum)
        {                
            if ((string) parameter == "brush")
                return "Red"; // return brush here!

            // if not pre-defined parameter (null or any other), return description
            return (int) value; // return enum description here!
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

用法:

<Label Content="{Binding MailSettingState, Converter={StaticResource 
EnumConverterSpec}}" 
BorderBrush="{Binding MailSettingState, Converter={StaticResource 
EnumConverterSpec}, ConverterParameter='brush'}" />