简体   繁体   English

如何在WPF C#中将组合框绑定到字典

[英]How To Bind a Combobox to a Dictionary in WPF C#

I'm trying to bind a combobox to a dictionary and display a specific field within the currently selected object in WPF. 我试图将组合框绑定到字典,并在WPF中当前选定的对象内显示特定字段。

What I want displayed in the combobox: ("I will do it" is initally selected) 我想要在组合框中显示的内容:(最初选择了“我会做”)
I will do it 我会做的
I will not do it 我不会这样做
I might do it 我可能会做

What is actually displayed currently: (nothing is initally selected) 当前实际显示的内容:(最初未选择任何内容)
[YES, AnswerDisplayItem] [是,answerDisplayItem]
[No, AnswerDisplayItem] [否,answerDisplayItem]
[MAYBE, AnswerDisplayItem] [MAYBE,answerDisplayItem]

Here's my code: 这是我的代码:

public enum Answer { YES, NO, MAYBE}

public class AnswerDisplayItem
{
    public string DisplayName { get; }
    public string DisplayDescription { get; }
    public AnswerDisplayItem(string displayName, string displayDescription)
    {
        DisplayName = displayName;
        DisplayDescription = displayDescription;
    }
}


public class MyViewModel()
{
    public MyViewModel() 
    {
        AnswerDisplay = new Dictionary<Answer, AnswerDisplayItem>
        {
            {Answer.YES, new AnswerDisplayItem("Yes", "I will do it") },
            {Answer.NO, new AnswerDisplayItem("No", "I will not do it")},
            {Answer.MAYBE, new AnswerDisplayItem("Maybe", "I might do it")}
        };
        SelectedAnswer = Answer.Yes;
    }


    public Dictionary<Answer, AnswerDisplayItem> AnswerDisplay{ get; private set; }

    private Answer _selectedAnswer;
    public Answer SelectedAnswer
    {
        get
        {
            return _selectedAnswer;
        }
        set
        {
            if (_selectedAnswer != value)
            {
                _selectedAnswer = value;
                RaisePropertyChanged();
            }
        }
    }
}

XAML: XAML:

<ComboBox ItemsSource="{Binding AnswerDisplay}" 
          DisplayMemberPath="Value.DisplayDescription"
          SelectedItem="{Binding SelectedAnswer}"/>

Use a Dictionary<Answer,string> (no need for another class) 使用Dictionary<Answer,string> (不需要其他类)

AnswerDisplay = new Dictionary<Answer, string>
{
    {Answer.YES, "I will do it"},
    {Answer.NO,  "I will not do it"},
    {Answer.MAYBE, "I might do it"},
};

and bind it to the ComboBox 并将其绑定到ComboBox

<ComboBox ItemsSource="{Binding AnswerDisplay}" 
          DisplayMemberPath="Value"
          SelectedValuePath="Key"
          SelectedValue="{Binding SelectedAnswer}"/>

Update 更新资料

If you want to use your dictionary, then change the binding to 如果要使用字典,则将绑定更改为

<ComboBox ItemsSource="{Binding AnswerDisplay}" 
          DisplayMemberPath="Value.DisplayDescription"
          SelectedValuePath="Key"
          SelectedValue="{Binding SelectedAnswer}"/>

The desired functionality can be easily achieved by binding to key value property generated from enum: 通过绑定到枚举生成的键值属性,可以轻松实现所需的功能:

Define the enum: 定义枚举:

 public enum DateModes
{
    [Description("DAYS")]
    Days,
    [Description("WKS")]
    Weeks,
    [Description("MO")]
    Month,
    [Description("YRS")]
    Years
 }

The following helper method will return the KeyValue pairs 以下帮助器方法将返回KeyValue对

 public static string Description(this Enum eValue)
    {
        var nAttributes = eValue.GetType().GetField(eValue.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (nAttributes.Any())
        {
            var descriptionAttribute = nAttributes.First() as DescriptionAttribute;
            if (descriptionAttribute != null)
                return descriptionAttribute.Description;
        }

        // If no description is found, the least we can do is replace underscores with spaces
        TextInfo oTI = CultureInfo.CurrentCulture.TextInfo;
        return oTI.ToTitleCase(oTI.ToLower(eValue.ToString().Replace("_", " ")));
    }     
public static IEnumerable<KeyValuePair<string, string>> GetAllValuesAndDescriptions<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable
    {
        if (!typeof(TEnum).IsEnum)
        {
            throw new ArgumentException("TEnum must be an Enumeration type");
        }

        return from e in Enum.GetValues(typeof(TEnum)).Cast<Enum>()
               select new KeyValuePair<string, string>(e.ToString(), e.Description());
    }

Property in the ViewModel (or DataContext): ViewModel(或DataContext)中的属性:

public IEnumerable<KeyValuePair<string, string>> DateModes { get { return EnumHelper.GetAllValuesAndDescriptions<DateModes>(); } }

Binding in the View: 在视图中绑定:

                  <ComboBox 
                      ItemsSource="{Binding DateModes}"
                      SelectedValue="{Binding SelectedDateDisplay}"
                      DisplayMemberPath="Value"
                      SelectedValuePath="Key"
                      VerticalAlignment="Top"/>

What you want to display is nothing but the description attribute of the enum. 您想要显示的只是枚举的description属性。 I feel this method will be a lot cleaner. 我觉得这种方法会干净很多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM