【问题标题】:c# Wpf binding an enum to comboboxc# Wpf 将枚举绑定到组合框
【发布时间】:2018-11-12 11:26:48
【问题描述】:

我在将 WeekDay 枚举绑定到组合框时遇到问题。 NutritionPlan 绑定效果很好。

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

【问题讨论】:

标签: c# wpf enums combobox binding


【解决方案1】:

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

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

绑定字典;

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2020-02-07
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      相关资源
      最近更新 更多