CheckedListBox 数据绑定到项目的选中状态

CheckedListBox data binding to checked state of Items

我试过像这样设置 CheckedListBox 的数据源:

private void Form1_Load(object sender, EventArgs e)
    {
        checkedListBox1.DisplayMember = "Name";
        checkedListBox1.ValueMember = "Checked";
        _bindingList = new BindingList<CustomBindingClass>(
            new List<CustomBindingClass>
        {
            new CustomBindingClass {Checked = CheckState.Checked, Name = "Item1"},
            new CustomBindingClass {Checked = CheckState.Checked, Name = "Item2"},
            new CustomBindingClass {Checked = CheckState.Unchecked, Name = "Item3"},
        });
        checkedListBox1.DataSource = _bindingList;
    }

它正在工作,但部分工作。我可以稍后再做休闲活动

_bindingList.RemoveAt(0);

_bindingList[0].Name = "TestTest"; 和 CheckedListBox 更新良好,但项目未选中。这不起作用

_bindingList[0].Checked=CheckState.Checked;

当我的 CustomBindingClass 中的 Checked属性 是 bool 类型时,我也测试过这样做,但也不起作用。任何建议 ValueMember 属性 的类型应该是什么?

如果您查看 CheckedListBox class,您会注意到 DataSourceDisplayMemberValueMember 标记为

[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]

这是 Windows 表单控件中使用的一种常用技术,用于指示从基础 class 继承的某些 public 属性(因此无法删除)不适用于该具体派生class 不应使用。

CheckedListBox 的上述属性必须有这样做的理由。正如您已经看到的,它是 "sort of working",但关键是它根本不能保证工作。所以不要使用它们。如果您愿意,可以创建一个包含 CheckedListBoxBindingList 的助手 class,侦听 ListChanged 事件并同步控件。

考虑这些事实:

  1. CheckedListBox 没有用于检查项目的内置数据绑定支持。您需要自己处理项目的检查状态。

  2. 你设置了checkedListBox1.ValueMember = "Checked";。你没有设置项目检查状态,你只是说当你 select 项目时, returns by SelectedValue 的值来自你的 Checked 属性被选中项后面的对象。例如,您可以在 ButtonClick 事件中使用此代码来查看结果;无论项目的检查状态如何,消息框都将显示项目后面的对象的 Checked 属性 的值:

    MessageBox.Show(checkedListBox1.SelectedValue.ToString());
    
  3. 选择项目和检查项目是完全不同的。

我更喜欢使用 DataGridView 来达到这样的目的。您可以简单地拥有一个 CheckBox 列和一个只读 TextBox 列并将 DataGridView 绑定到您的对象列表。

如果您需要双向数据绑定,则无论您使用什么控件来显示数据,都需要实现 INotifyPropertyChanged 接口。如果您不实现该接口,则在更改模型的属性时 ListChange 事件不会引发,并且您无法自动看到 UI 中的更改。