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

时间:2018-06-02 15:20:11

标签: c# wpf enums combobox binding

我有一个问题将我的WeekDay枚举绑定到一个组合框。营养计划的绑定效果很好。

这是我的.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>

2 个答案:

答案 0 :(得分:0)

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

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

绑定字典;

答案 1 :(得分:0)

如果您希望能够简单地从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>

然后你所做的只是将你的Enum作为上面的xaml中的Enum类型传递。通过这种方式,您可以使用xaml中使用枚举的通用方法。

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