我想要在我的ViewModel上有一個枚舉,讓我們來說代表一個人的性別。代表該ViewModel的視圖應該能夠呈現提供該值的方式;無論是一組單選按鈕還是一個組合框(如果有很多)。在這裏有很多例子,你在XAML中硬編碼單選按鈕,每個按鈕代表它代表了它的值。而更好的人也將使用顯示屬性的名稱來提供單選按鈕的文本。動態綁定到一個枚舉
我期待着更進一步。我希望根據Enum的值和DisplayAttribute的名稱和描述等動態生成 RadioButtons。理想情況下,我希望它選擇創建一個ComboBox(而不是RadioButtons),如果它超過6個項目(可能實現爲某種控件);但讓我們看看我們是否可以在我們嘗試跑步之前走路。 :)
我的谷歌搜索讓我很接近......這裏就是我的了:
public enum Gender
{
[Display(Name="Gentleman", Description = "Slugs and snails and puppy-dogs' tails")]
Male,
[Display(Name = "Lady", Description = "Sugar and spice and all things nice")]
Female
}
窗口:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:EnumMultiConverter x:Key="EnumMultiConverter"/>
<ObjectDataProvider
MethodName="GetValues"
ObjectType="{x:Type local:EnumDescriptionProvider}"
x:Key="AdvancedGenderTypeEnum">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:Gender"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<StackPanel>
<ItemsControl ItemsSource="{Binding Source={StaticResource AdvancedGenderTypeEnum}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="{Binding GroupName}" Content="{Binding Name}" ToolTip="{Binding Description}">
<RadioButton.IsChecked>
<MultiBinding Converter="{StaticResource EnumMultiConverter}" Mode="TwoWay">
<Binding RelativeSource="{RelativeSource AncestorType=ItemsControl}" Path="DataContext.Gender" Mode="TwoWay" />
<Binding Path="Value" Mode="OneWay"/>
</MultiBinding>
</RadioButton.IsChecked>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Window>
EnumDescriptionProvider:
public static class EnumDescriptionProvider
{
public static IList<EnumerationItem> GetValues(Type enumType)
{
string typeName = enumType.Name;
var typeList = new List<EnumerationItem>();
foreach (var value in Enum.GetValues(enumType))
{
FieldInfo fieldInfo = enumType.GetField(value.ToString());
var displayAttribute = (DisplayAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DisplayAttribute));
if (displayAttribute == null)
{
typeList.Add(new EnumerationItem
{
GroupName = typeName,
Value = value,
Name = value.ToString(),
Description = value.ToString()
});
}
else
{
typeList.Add(new EnumerationItem
{
GroupName = typeName,
Value = value,
Name = displayAttribute.Name,
Description = displayAttribute.Description
});
}
}
return typeList;
}
}
EnumerationItem:
public class EnumerationItem
{
public object GroupName { get; set; }
public object Value { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
而多轉換器(因爲的IValueConverter不能把綁定的ConverterParameter):
public class EnumMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0].Equals(values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
所以,我所擁有的唯一的問題是,我不能做ConvertBack。但也許有人有一個很好的解決方案。正如我所說,理想情況下,我只想要一些可以綁定到ViewModel上的枚舉的魔法控件,併爲它爲該枚舉的每個值動態創建RadioButton。但我會採取我能得到的任何建議。
爲什麼當字典能夠很好地完成這個任務時,你想要使用Enum,當我們有編譯時間常量時使用枚舉。 在你的情況'''詞典<字符串,DisplayAttribute>'''會做一樣好 –
罷工上面我誤解了問題 –
你爲什麼要回來轉換?您已經擁有索引 - 只需將選定的索引綁定到視圖模型,並且可以將索引(一個int)轉換爲枚舉。 – code4life