【问题标题】:How To Bind a Combobox to a Dictionary in WPF C#如何在 WPF C# 中将组合框绑定到字典
【发布时间】:2017-05-24 00:11:29
【问题描述】:

我正在尝试将组合框绑定到字典并在 WPF 中当前选定的对象中显示特定字段。

我想在组合框中显示的内容:(“我会做”是最初选择的)
我会做的
我不会这样做
我可能会这样做

当前实际显示的内容:(最初没有选择任何内容)
[是,AnswerDisplayItem]
[不,AnswerDisplayItem]
[可能,AnswerDisplayItem]

这是我的代码:

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:

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

【问题讨论】:

  • 字典包含 KeyValuePair 的集合,该集合具有 Key 和 Value 属性。绑定该属性。顺便说一句 Dictionary 应该可以完成这项工作
  • 这是我的意思,我不想使用字典。我想要一个 AnswerDisplayItem,因为我需要在我的视图模型中访问其他字段。在这种情况下,无论我做什么,我似乎都无法正确绑定。
  • 没有必要但可以使用字典

标签: c# wpf mvvm data-binding combobox


【解决方案1】:

使用Dictionary&lt;Answer,string&gt;(不需要其他类)

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

并将其绑定到ComboBox

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

更新

如果要使用字典,请将绑定更改为

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

【讨论】:

  • 你的回答很有道理。尽管组合框值现在已初始化,但我仍然没有得到预期的结果。嗯,我的组合框样式可能有错误...
【解决方案2】:

通过绑定到从枚举生成的键值属性可以轻松实现所需的功能:

定义枚举:

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

以下帮助方法将返回 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());
    }

ViewModel(或 DataContext)中的属性:

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

在视图中绑定:

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

你想要显示的只是枚举的描述属性。我觉得这种方法会干净很多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 2016-02-18
    • 2018-12-26
    • 2018-11-12
    • 2020-02-07
    • 2010-11-09
    相关资源
    最近更新 更多