c# Wpf 将枚举绑定到组合框



我在将工作日枚举绑定到组合框时遇到问题。营养计划绑定效果很好。

这是我的 .xaml 代码:

<Page x:Class="WpfApp.Views.AddDailyNutritionPlan"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:local="clr-namespace:WpfApp.Views"
mc:Ignorable="d" 
d:DesignHeight="450" d:DesignWidth="800"
Title="AddDailyNutritionPlan">
<Grid Background="#A4EE6A" >
<ComboBox Name="cmbnutritionplan" ItemsSource="{Binding NutritionPlans}" 
HorizontalAlignment="Left" VerticalAlignment="Top" Width="120" Margin="119,36,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding NutritionPlanName}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox Name="cmbweekday" ItemsSource="{Binding Path=WeekDays}" HorizontalAlignment="Left" 
VerticalAlignment="Top" Width="120" Margin="119,72,0,0" RenderTransformOrigin="1.701,0.613">
</ComboBox>
</Grid>

如果希望能够简单地绑定 XAML 中的枚举,则可以编写标记扩展类。前段时间我写了一篇关于它的博客文章: http://simonkatanski.blogspot.com/2013/02/enum-combobox-using-markupextension.html

代码如下:

public class EnumValuesExtension : MarkupExtension
{
private Type _enumType;
private String _resourceName;
private bool _addEmptyValue = false;
// Enumeration type
public Type EnumType
{
set { _enumType = value; }
}
// Name of the class of the .resx file        
public String ResourceName
{
set { _resourceName = value; }
}
// Add empty value flag        
public Boolean AddEmptyValue
{
set { _addEmptyValue = value; }
}
public EnumValuesExtension()
{
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
// Enumeration type not passed through XAML
if (_enumType == null)
throw new ArgumentNullException("EnumType (Property not set)");
if (!_enumType.IsEnum)
throw new ArgumentNullException("Property EnumType must be an enum");
// Bindable properties list
List<dynamic> list = new List<dynamic>();
if (!String.IsNullOrEmpty(_resourceName))
{
// Name of the resource class
Type type = Type.GetType(_resourceName);
if (type == null)
throw new ArgumentException(
"Resource name should be a fully qualified name");
// We iterate through the Enum values
foreach (var enumName in Enum.GetNames(_enumType))
{
string translation = string.Empty;
var property = type.GetProperty(enumName,
BindingFlags.Static |
BindingFlags.Public |
BindingFlags.NonPublic);
// If there's not translation for specific Enum value,
// there'll be a message shown instead
if (property == null)
translation = String.Format(
"Field {0} not found in the resource file {1}",
enumName,
_resourceName);
else
translation = property.GetValue(null, null).ToString();
list.Add(GetNamed(translation, enumName));
}
// Adding empty row
if (_addEmptyValue)
list.Add(GetEmpty());
return list;
}
// If there's no resource provided Enum values will be used
// without translation
foreach (var enumName in Enum.GetNames(_enumType))
list.Add(GetNamed(enumName, enumName));
if (_addEmptyValue)
list.Add(GetEmpty());
return list;
}
// Create one item which will fill our ComboBox ItemSource list
private dynamic GetNamed(string translation, string enumName)
{
// We create a bindable context
dynamic bindableResult = new ExpandoObject();
// This dynamically created property will be
// bindable from XAML (through DisplayMemberPath or wherever)
bindableResult.Translation = translation;
// We're setting the value, which will be passed to SelectedItem
// of the ComboBox
bindableResult.Enum = enumName;
return bindableResult;
}
// Create one empty item which will fill our ComboBox ItemSource list
private dynamic GetEmpty()
{
dynamic bindableResult = new ExpandoObject();
bindableResult.Translation = String.Empty;
bindableResult.Enum = null;
return bindableResult;
}
}

您可以在代码中像这样使用此类:

<StackPanel>
<ComboBox Height="100" Width="200"
SelectedValuePath="Enum" 
DisplayMemberPath="Translation"
ItemsSource="{Binding Source={local:EnumValues EnumType=local:TestEnum}}"
Margin="98,0,76,0"
SelectedValue="{Binding SelectedItemInYourViewModel}"/>
</StackPanel>

然后,您要做的就是将您的枚举作为上述 xaml 中的枚举类型传递。这样,您就可以使用来自 xaml 的枚举的通用方法。

我粘贴在这里的版本和博客中的版本有额外的代码,用于在组合中热切换值及其翻译的等效项(如果您正在处理多语言应用程序( - 您应该能够轻松删除该代码。

我现在没有具体细节,但我所做的是这样的事情。

enum WeekDay { Mon, Tues };
Dictionary<string, WeekDay> dic = new Dictionary<string, WeekDay>();
foreach (var v in WeekDay.Enumerate)  //this is not the correct syntax 
{
dic.Add(v.ToString(), v);
}

绑定字典;

最新更新