我有一个简单的ComboBox
,它有一些简单的值。我正在尝试使用我的模型上的枚举属性进行双向绑定。
<ComboBox d:LayoutOverrides="Height" Grid.Column="1" SelectedItem="{Binding SortType, Converter={StaticResource sortSelect}, Mode=TwoWay}">
<ListBoxItem Content="Ascending" Tag="Ascending"/>
<ListBoxItem Content="Descending" Tag="Descending"/>
<ListBoxItem Content="Absolute Ascending" Tag="AbsoluteAscending"/>
<ListBoxItem Content="Absolute Descending" Tag="AbsoluteDescending" />
</ComboBox>
这是我的ValueConverter
public class RdiSortMatchConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = (RdiSort) value;
switch (val)
{
case RdiSort.Ascending:
return "Ascending";
case RdiSort.Descending:
return "Descending";
case RdiSort.AbsoluteAscending:
return "Absolute Ascending";
case RdiSort.AbsoluteDescending:
return "Absolute Descending";
default:
throw new ArgumentOutOfRangeException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (RdiSort) Enum.Parse(typeof (RdiSort), (string) ((ListBoxItem) value).Tag);
}
}
ConvertBack
方法工作正常,并根据Tag
中的ListBoxItem
值更新我的模型,但我无法获得初始Enum
值以选择正确的ListBoxItem
了解实现这一目标的最佳方法,还是有更好的方法来约束Enums
(考虑到我需要每个Enum
值的自定义说明。
答案 0 :(得分:2)
你可以这样做。首先为每个枚举值添加说明
public enum RdiSort
{
[Description("Ascending Description")]
Ascending,
[Description("Descending Description")]
Descending,
[Description("AbsoluteAscending Description")]
AbsoluteAscending,
[Description("AbsoluteDescending Description")]
AbsoluteDescending
}
然后为您的ComboBox使用ObjectDataProvider
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:MyEnumerations="clr-namespace:MyEnumerations"
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="RdiSortValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="MyEnumerations:RdiSort" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
在ComboBox中使用RdiSortValues提供程序,并使用TextBlock和Converter创建一个DataTemplate,以查看Description而不是Enum值。
<local:EnumDescriptionConverter x:Key="EnumDescriptionConverter"/>
<ComboBox SelectedItem="{Binding SortType}"
ItemsSource="{Binding Source={StaticResource RdiSortValues}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
最后是转换器。不需要ConvertBack,因为转换器仅在TextBlock中用于显示。
public class EnumDescriptionConverter : IValueConverter
{
private string GetEnumDescription(Enum enumObj)
{
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
{
return enumObj.ToString();
}
else
{
DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
return attrib.Description;
}
}
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
RdiSort myEnum = (RdiSort)value;
string description = GetEnumDescription(myEnum);
return description;
}
return null;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
答案 1 :(得分:0)
这是我所做的解决方案。
.xaml =&gt;
<UserControl.Resources>
<c:PriorityConvertor x:Key="priorityConvertor"></c:PriorityConvertor>
</UserControl.Resources>
.cs file =&gt;
public class PriorityConvertor : IValueConverter
{
#region IValueConverter Members
object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
{
return string.Empty;
}
if (value.ToString() == "1")
{
return "High";
}
else if (value.ToString() == "2")
{
return "Medium";
}
else if (value.ToString() == "3")
{
return "Low";
}
return "Low";
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}