【问题标题】:Binding to nested property only showing first item in list绑定到嵌套属性仅显示列表中的第一项
【发布时间】:2014-01-15 14:21:28
【问题描述】:

我正在尝试将 .NET 4.5 中的 C# Winforms 中的 ListBox 控件绑定到具有我希望用于 DisplayMember 的嵌套属性的对象列表。它有点工作,除了当我将 DisplayMember 设置为嵌套属性时,即使列表中绑定了两个项目,列表框也只显示一个项目。如果我注释掉设置 DisplayMember 的代码,listBox 会显示两个项目。这是框架中的错误吗?如果可以的话,我想避免添加另一个属性或覆盖 ToString(),因为我正在实现 MVP,并且希望将我的视图逻辑与我的视图隔离。下面是一些示例代码。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        var bindingSource = new BindingSource();
        var listOfMyItems = new BindingList<MyItem>
        { 
          new MyItem { Number = 1, NestedItem = new NestedItem { Name = "name1", Note = "note1" } },
          new MyItem { Number = 2, NestedItem = new NestedItem { Name = "name2", Note = "note2" } },
        };
        bindingSource.DataSource = listOfMyItems;
        listBox1.DataSource      = bindingSource;
        //comment out the line below and the listBox1 will show 2 items
        listBox1.DisplayMember   = "NestedItem.Name";
    }
}
public class NestedItem
{
    public string Name { get; set; }
    public string Note { get; set; }
}
public class MyItem
{
    public NestedItem NestedItem { get; set; }
    public int Number { get; set; }
}

【问题讨论】:

    标签: c# winforms data-binding listbox bindingsource


    【解决方案1】:

    似乎将DisplayMember 设置为“NestedItem.Name”仅显示SelectedItemNestedItem.Name 属性-我对此进行了测试,如果 SelectedItem 更改,显示的名称也会相应更改-。最简单的解决方法是add another property for DisplayMember

    public class MyItem
    {
        public NestedItem NestedItem { get; set; }
        public int Number { get; set; }
        public String NestedItemName { get { return NestedItem.Name; } }
    }
    

    然后设置DisplayMember

    listBox1.DisplayMember   = "NestedItemName";
    

    不优雅,但仍然比使用herehere 建议的属性描述更容易。

    更新:

    以下是我做的一个快速测试。添加一个按钮来切换listBox1's DisplayMemberOnclick 事件处理程序:

    listBox1.DisplayMember = (listBox1.DisplayMember == "Number") ? "NestedItem.Name" : "Number";
    

    DisplayMember 设置为“数字”时,您可以选择列表中的任何项目-不一定是第一项-,然后再次单击该按钮。你会看到 SelectedItem's NestedItem.Name 显示出来。

    【讨论】:

    • 你是如何测试 selectedItem 的变化的?因为当我输入代码 listBox1.SelectedIndex = 1;我得到一个参数超出范围异常。我真的想避免尝试拥有另一个仅用于显示的属性,因为我正在尝试实现 MVP 并希望将视图逻辑与我的视图隔离。但如果没有实际的解决方案,那么我可能不得不采用这种解决方法。
    • 检查我的更新,看看我是如何进行测试的。正如第一个链接中所建议的那样,您可以在另一个部分类中分离仅用于显示的属性,这样它就不会与原始模型属性混淆 -至少,尽管在逻辑上它仍然是单个类,但在物理上是分开的 -.
    • 完美,我添加了一个 Get-Only 属性: public string DisplayMember { get { return ToString(); } } 得到我的公共方法:公共覆盖字符串 ToS​​tring() 现在列表框工作得很好。
    猜你喜欢
    • 2011-06-29
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 2017-10-26
    • 2021-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    相关资源
    最近更新 更多