我将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>

最佳答案

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

我在此处粘贴的版本以及博客中的版本均具有用于将值与转换后的等效项组合使用的热切换值的额外代码(如果您正在使用多语言应用程序)-您应该能够轻松删除该代码。

关于c# - C#WPF将枚举绑定(bind)到组合框,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50658353/

10-16 22:03