代码之家  ›  专栏  ›  技术社区  ›  Rkurel

C WPF将枚举绑定到组合框

  •  2
  • Rkurel  · 技术社区  · 6 年前

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

    这是我的.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 回复  |  直到 6 年前
        1
  •  0
  •   Simon Katanski    6 年前

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

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

        2
  •  0
  •   paparazzo    6 年前

    我现在不知道具体情况,但我做的是这样的事情。

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

    装订字典;