绑定一个ReactiveList到一个组合框

本文关键字:一个 组合 ReactiveList 绑定 enum | 更新日期: 2023-09-27 18:10:51

我已经看到了很多在WPF中将ReactiveList绑定到ComboBox控件的解决方案,这样控件就可以显示枚举项的描述。所有这些解决方案都在XAML中使用标准的TypeConverter和绑定,但我使用的是ReactiveUI,因此我希望在后面的代码中执行绑定。在没有任何转换的情况下,我得到的原始枚举值是字符串,而不是它们的描述,所以至少我知道绑定工作正常,但我还没有弄清楚转换。

我很确定我需要使用IBindingTypeConverter(并使用Splat注册它),但我似乎无法在我的转换器中找到toType和fromType的正确组合来实现这一点。我尝试了以下操作,部分成功:

public class MyEnumToStringConverter : IBindingTypeConverter
{
    public int GetAffinityForObjects(Type fromType, Type toType)
    {
        if (fromType == tyepof(ReactiveList<MyEnumType>))
        {
            return 100;
        }
        return 0;
    }
    public bool TryConvert(object from, Type toType, object conversionHint, out object result)
    {
        ...
    }
}

在调试器中,GetAffinityForObjects()在调用绑定ComboBox的ItemsSource期间被击中并返回100,但TryConvert从未被调用。

谁能提供一个很好的例子,这样做正确的方式在ReactiveUI?

绑定一个ReactiveList<enum>到一个组合框

只是一个想法,它有很多东西:DisplaySystem.ComponentModel.DataAnnotations名称空间的一部分,但您可以使用另一个名称空间,只需更改DisplayName方法

public enum CoolEnum {
    [Display(Name="Value 1")]
    Value1,
    [Display(Name="Value 2")]
    Value2,
}
public static class EnumExtensions
{
    public static string DisplayName(this Enum value)
    {
        Type enumType = value.GetType();
        var enumValue = Enum.GetName(enumType, value);
        MemberInfo member = enumType.GetMember(enumValue)[0];
        var attrs = member.GetCustomAttributes(typeof(DisplayAttribute), false);
        var outString = ((DisplayAttribute)attrs[0]).Name != null ? ((DisplayAttribute)attrs[0]).Name : enumValue; //TODO Null check
        if (((DisplayAttribute)attrs[0]).ResourceType != null)
        {
            outString = ((DisplayAttribute)attrs[0]).GetName();
        }
        return outString;
    }
}

像这样使用:

var enumValue = CoolEnum.Value1;
var displayValue = enumValue.DisplayName();

在XAML中可以使用ValueConverter

public class EnumToDisplayName : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try 
        {
            var enumValue = (CoolEnum)value;
            return enumValue.DisplayName();
        }
        catch (Exception){
        }
        return string.Empty;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return System.Windows.DependencyProperty.UnsetValue;
    }
}

在绑定数据的XAML内部,将转换器映射为资源并使用它:

<UserControl.Resources>
    <local:EnumToDisplayValue x:Key="enumToDisplayValue" />
</UserControl.Resources>
Text="{Binding enumValue, Converter={StaticResource enumToDisplayValue}}"

只是一个开始的想法,有乐趣的编码:)