65.9K
CodeProject 正在变化。 阅读更多。
Home

完全数据绑定的CheckedListBox

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (15投票s)

2008年4月19日

CPOL

3分钟阅读

viewsIcon

82189

downloadIcon

2044

BoundCheckedListBox 可以绑定到代表多对多数据关系的三个表。

manytomanytest-src

引言

您可能已经知道,.NET CheckedListBox 不提供任何数据绑定,尽管在您具有带有关系表的多对多数据关系时,它似乎是适用的;例如,一个产品可以是多个类别的一部分,并且每个类别可以包含多个产品。

所以,我的任务是使 CheckedListBox 再次可绑定。

背景

如果您在 CodeProject 上搜索可绑定的 CheckedListBox,您会找到两三个。 我也这样做了。 但是,当我仔细观察它们时,我注意到它们没有实现新的数据绑定工具,而是重新激活了 listbox 数据绑定到单个表 - 这意味着项目列表将被数据绑定。 复选框必须或多或少地手动设置。 有关详细信息,请参见 可绑定的 CheckedListBox带有 CheckedListBox 作为下拉列表的 ComboBox

这不是我想要的。 我希望 CheckedListBox 是完全数据可绑定的;例如,保存类别列表并根据数据源(其中一个保存当前选择的产品)自动设置选中状态,并且如果用户(取消)选中某个项目,则添加/删除关系表的条目。 玩示例应该可以清楚地说明这一点。

所以,下一个问题是如何创建我自己的数据绑定。 我对这应该如何工作有一个基本的想法,但这篇文章对我有很大帮助: 在自定义控件中实现复杂的数据绑定

BoundCheckedListBox 不仅绑定到一个数据源,它绑定到三个数据源,并且需要五个数据成员。

使用代码

示例显示了哪个人喜欢哪些水果。

所以,我们需要

  • 父表的数据源, Personen
  • 子表的数据源, Fruechte
  • 关系表的数据源, p_f
  • 父 ID 列的数据成员, ID (Personen.ID)
  • 子 ID 列的数据成员, ID (Fruechte.ID)
  • 子显示列(保存 ListBox 中显示的项目)的数据成员, Name (Fruechte.Name)
  • 关系表中保存 ID 的两列的两个数据成员

以下是如何设置这些(或通过设计视图中的属性列表)

boundCheckedListBox1.ChildDisplayMember = "Name";
boundCheckedListBox1.ChildValueMember = "fID";
boundCheckedListBox1.ParentValueMember = "pID";
boundCheckedListBox1.ParentIDMember = "ID";
boundCheckedListBox1.ChildIDMember = "ID";
boundCheckedListBox1.ParentDataSource = parentBindingSource;
boundCheckedListBox1.ChildDataSource = childBindingSource;
boundCheckedListBox1.RelationDataSource = relationBindingSource;

其中每个数据源都是一个绑定源,具有一个数据集作为数据源,并具有相应的表作为数据成员。看看源代码。

关注点

非常重要的是,BoundCheckedListBox 从数据源获取货币管理器,而不是属性管理器(因为它不提供列表,将引发异常)。我发现使用 DataSet.Table 作为数据源只想给我属性管理器。因此,我使用了绑定源。

设置默认值,如果创建新的 DataRow 且未设置任何值,则不会引发异常。我只能调用货币管理器的 AddNew 方法,之后会设置这些值。

使用绑定源的 EndEdit 函数。我有一个按钮向子表中添加一个新元素,文本框设置名称。 例如

EventHandler dataChangedHandler = new EventHandler(dataChanged);
....
button_kat_add.Click += dataChangedHandler;
button_kat_del.Click += dataChangedHandler;
....
textBox_kat_name.LostFocus += dataChangedHandler;
....

void dataChanged(object sender, EventArgs e) {
     dataTable1BindingSource.EndEdit();
     ....BindingSource.EndEdit();
     ....BindingSource.EndEdit();
     ....relationBindingSource.EndEdit();
}
......

private void button_kat_add_Click(object sender, EventArgs e) {
    this.....BindingSource.AddNew();
}

private void button_kat_del_Click(object sender, EventArgs e) {
     if (kategorienBindingSource.Current != null)
         this.kategorienBindingSource.RemoveCurrent();
}

如果取消选中复选框,则关系表中的 DataRow 将被删除。 因此,我们最终可能会得到多个具有相同 ID 的已删除行。 应该通过取消删除行来改进这一点。

欢迎发表评论和更新!

历史

  • 2008 年 4 月 19 日 - 初始版本
© . All rights reserved.