首先,我想谈谈普通绑定(带有标准属性,例如文本框的文本)。这里的示例网格只有 2 行(为简单起见)。假设我有一个包含 2 列(ID 和名称)的 2 行表 (myDataTable)、一个 DataGridView (myGrid) 和一个 TextBox (myTextBox)。下面是绑定数据的代码:
myGrid.DataSource = myDataTable;
myTextBox.DataBindings.Add("Text", myDataTable, "Name");
绑定数据后,当网格中的选择发生变化时,信息会自动更新到控件TextBox中,例如2行是:
ID | Name
1 .NET
2 Java
一开始,grid 中的选择在索引 0,myTextBox 的 Text 是“.NET”,将选择移动到下一个位置(在索引 1),myTextBox 的 Text 是“Java”,一次又一次地移动,向前和向后,它可以按我的预期工作。但是现在我有一个带有一个名为 List 的自定义属性的控件,这是 List 的类型并且是只读的。我想将它绑定到表的列(例如,名称),我执行相同的绑定规则,但是在更新到数据源(myDataTable)之前添加一点自定义解析以格式化正确的字符串,因为我的自定义属性是类型列出我的名称列是字符串类型,这是绑定代码:
Binding bind = new Binding("List", myDataTable, "Name"){
ControlUpdateMode = ControlUpdateMode.Never //Because my List property is readonly
};
//formating string data before updating to the datasource
bind.Parse += (s,e) => {
List<string> data = (List<string>) e.Value;
if(data.Count == 0) e.Value = DBNull.Value;
else e.Value = string.Join(",",data.ToArray());//format as comma separated string
};
myCustomControl.DataBindings.Add(bind);
在这种情况下,假设 myDataTable 当前在 Name 列中没有数据,如下所示:
ID | Name
1 <DBNull.Value> <--- current index
2 <DBNull.Value>
运行demo后,当前网格中的选择索引为0,我尝试改变myCustomControl属性List的值(Items,而不是引用),例如更新如下:
myCustomControl.List.Add(".NET");
myCustomControl.List.Add("Java");
然后,将网格中的选择移动到下一个位置(索引 1),值“.NET,Java”将更新到数据源中第 0 行的名称列,如下所示:
ID | Name
1 .NET,Java
2 <----- current index
现在,如果我将选择移回索引 0,则第 1 行中 Name 列的值也会更新为“.NET,Java”,如下所示:
ID | Name
1 .NET,Java <----- current index
2 .NET,Java
这不是我想要的。我的意思是应该通过控件 myCustomControl 更新该值。这是我想要的:
ID | Name
1 .NET,Java <----- current index
2
我可以理解,在从索引 1 移回索引 0 时,List 属性的值仍然是一个具有 2 个项目(“.NET”和“Java”)的 List,因此在移动之后,它被更新为cell at column Name in row 1. I'm finding how to reset that value of List property after it's updated to the cell at column Name in row 0 so that when the selection is at index 1, it's already empty. 我尝试将 Parse 事件处理程序更改为以下内容,但效果不佳:
bind.Parse += (s,e) => {
List<string> data = (List<string>) e.Value;
if(data.Count == 0) e.Value = DBNull.Value;
else e.Value = string.Join(",",data.ToArray());//format as comma separated string
//I think at here, the value has been already updated to the datasource
//and I can perform the reset
myCustomControl.List.Clear();
};
但似乎在值更新到数据源之前清除,因此没有更新到数据源的值(而不是“.NET,Java”,它是一个 DBNull.Value)。
然后我也试过这个:
bind.BindingComplete += (s,e) => {
if(e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate)
myCustomControl.List.Clear();
};
我想,它应该检查数据是否更新到数据源,列表可以清楚。我还尝试了一些标志在清除之前将其标记为真,并在清除后将其重置为假,使用此标志来控制 bind.Parse 中的流动,但它什么也没做。
你有解决这个问题的想法吗?您的帮助将不胜感激!谢谢你。