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

如何在wpf xaml中使用值转换器的特定属性,wpf,ivalueconverter,Wpf,Ivalueconverter,我有一个枚举到字符串的转换器 public class EnumToStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { MailSettingsStateEnum enumValue = (MailSettingsStateEnum)value

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

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


那么有没有一种方法可以让我只有一个转换器,它返回一个有两个属性的对象,我可以在xaml中使用这些属性?我可以创建转换器,很简单,但我不知道如何在xaml中使用它。假设转换器返回了一个对象,并且有两个名为MessageString(string类型)的属性和另一个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.
}

现在,您将有一个转换器来管理所有的转换器

您可以根据转换器中接收的
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;}
}

公共类EnumConverter:MarkupExtension,IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
var enumValue=(MailSettingsStateEnum)值;
返回新的ConvertedEnum{Label=enumValue.Description(),
BorderBrush=新的BorderBrush()};
}
//这与此无关。
公共覆盖对象ProviderValue(IServiceProvider服务提供程序)
{
归还这个;
}
} 
公共类兑换地
{
公共字符串标签{get;set;}
公共边界刷{get;set;}
}

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

我已经在上面发表了评论,但下面是解决方案

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

公共类EnumConverter:MarkupExtension,IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
var enumValue=(MailSettingsStateEnum)值;
返回新的ConvertedEnum{Label=enumValue.Description(),
BorderBrush=新的BorderBrush()};
}
//这与此无关。
公共覆盖对象ProviderValue(IServiceProvider服务提供程序)
{
归还这个;
}
} 
公共类兑换地
{
公共字符串标签{get;set;}
公共边界刷{get;set;}
}

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

转换器应该返回与请求的
targetType
匹配的对象。根据
参数
,转换器可以为输入
枚举
值返回不同的值。我认为它比仅仅依靠
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'}" />

转换器应返回与请求的
targetType
匹配的对象。根据
参数
,转换器可以为输入
枚举
值返回不同的值。我认为它比仅仅依靠
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'}" />


AFAIK不可能满足您的要求。转换器将返回您想要的任何对象,但输出仍然是一个结果。听起来有点老套,但您可以尝试将
标签的
DataContext
设置为转换对象(您需要为此创建一个类),然后绑定到它们的属性。尽管如此,我还是会使用两个独立的转换器。编辑测试和工作。谢谢大家。我才意识到我的愚蠢。我想要的方式是不可能的。所有这三个答案都是解决方案,但由于我只能选择其中一个,我为另外两个道歉。好吧,这不可能是你想要的。转换器将返回您想要的任何对象,但输出仍然是一个结果。听起来有点老套,但您可以尝试将
标签的
DataContext
设置为转换对象(您需要为此创建一个类),然后绑定到它们的属性。尽管如此,我还是会使用两个独立的转换器。编辑测试和工作。谢谢大家。我才意识到我的愚蠢。我想要的方式是不可能的。这三个答案都是解决方案,但由于我只能选择其中一个,我为另外两个道歉。