完全数据绑定的CheckedListBox
BoundCheckedListBox 可以绑定到代表多对多数据关系的三个表。
引言
您可能已经知道,.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 日 - 初始版本