Winforms Databound Combobox 更新数据但不改变 RowState
Posted
技术标签:
【中文标题】Winforms Databound Combobox 更新数据但不改变 RowState【英文标题】:Winforms Databound Combobox updates data but does not change RowState 【发布时间】:2021-01-21 20:09:26 【问题描述】:.NET 4.7.2 Winforms c#
有一个包含一堆组合框的表单。所有人的下拉列表。组合框由数据表或字典填充。它们绑定到数据集的数据表中的列。
像这样填充和绑定数据的组合框:
dSDO = new Dictionary<bool, string>
true,"Yes" ,
false,"No"
;
CB1.DataSource = new BindingSource(dSDO, null);;
CB1.DisplayMember = "Value";
CB1.ValueMember = "Key";
CB2.DataSource = _dtCommodity;
CB2.DisplayMember = "CommodityAbbr";
CB2.ValueMember = "CommodityID";
// Databindings tried both before and after
CB1.DataBindings.Add("SelectedValue", dataset, "Tablename.colname1", true, DataSourceUpdateMode.OnPropertyChanged);
CB1.DataBindings.Add("SelectedValue", dataset, 'Tablename.colname2", true, DataSourceUpdateMode.OnPropertyChanged);
在 ComboBox 中选择不同的项目会更新数据行中的列。但是,RowState 保持不变,并且不会发生对行的更新。为表单明确调用 ValidateChildren 没有任何作用。
此代码曾经在较旧的 .NET 框架(4.0 和更早版本)中工作;似乎发生了一些变化以中断处理,或者我遗漏了一些东西,微软不再那么宽容了。
有什么想法吗? 谢谢!
【问题讨论】:
您是否在加载数据后调用了dataset.AcceptChanges();
(将所有行的状态设置为Unchanged
)?此外,我将使用 BindingSource 来处理 DataSet(将 DataSet 设置为其 DataSource)并使用 BindingSource 来绑定 ComboBox(将 Binding 的 DataSource
成员设置为 BindingSource)。绑定到嵌套对象将以这种方式工作。当您通过 ComboBox 提交值时,行状态将为 Modified
。 ComboBox 的 DataSource 应该是实现了INotifyPropertyChanged
的对象(那里没有ListChanged
事件)。
我不调用 AcceptChanges -- 这会将状态设置为未更改。我会立即尝试这个建议。
首次加载数据时,应设置状态为Unchanged
,否则保持Added
,不正确。 DataAdapter 有一个属性[DataAdapter].AcceptChangesDuringFill
,正是用于此目的。
我的问题是数据更改后仍然显示不变。我更改了 ComboBox 中的选择,组合框新 selectedvalue 被写入 dataRow 但 RowState 未更改。将字段的数据绑定更改为数据集上的 bindingSource 并没有任何好处。结果相同。
将 BindingSource 添加为字段(例如,internal BindingSource bsDataSet = null;
),然后添加 bsDataSet = new BindingSource(dataset, null); CB1.DataBindings.Add("SelectedValue", bsDataSet, "Tablename.colname1", true, DataSourceUpdateMode.OnPropertyChanged);
。当然,您只添加一个DataBinding
,如果您尝试添加第二个,则会出现异常。顺便说一句,始终设置DisplayMember
和ValueMember
(按此顺序)在DataSource
之前。
【参考方案1】:
我找到了解决办法。
根据@Jimi 的建议,我更改了代码...
bsDataSource = new BindingSource(dataSet, "[SqlTableName]");
CB1.DataBindings.Add("SelectedValue", bsDataSource, "colname1", true, DataSourceUpdateMode.OnPropertyChanged);
CB2.DataBindings.Add("SelectedValue", bsDataSource, "colname2", true, DataSourceUpdateMode.OnPropertyChanged);
然后在存档中,我这样做了:
using (SqlDataAdapter da = new SqlDataAdapter(SqlCommandObject))
using (SqlCommandBuilder cb = new SqlCommandBuilder(da))
da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
cb.ConflictOption = ConflictOption.OverwriteChanges;
cb.SetAllValues = false;
da.InsertCommand = cb.GetInsertCommand(true);
da.UpdateCommand = cb.GetUpdateCommand(true);
da.DeleteCommand = cb.GetDeleteCommand(true);
try
// I Added this line
((DataRowView)bsDataSource.Current).EndEdit();
// End of what I added
da.MissingMappingAction = MissingMappingAction.Passthrough;
iRowCount = da.Update(ds, ds.Tables[0].TableName);
catch (Exception ex)
// [error handling]
这导致 RowState 更改为 Modified 并且数据集更新成功。
所以解决办法:
-
在 DataSet 对象上创建一个 BindingSource,其 TableName 为
相关的DataTable作为参数2
Data将每个控件绑定到相关的列名并指定BindingSource。
对 Current 属性中的 DataRowView 执行 EndEdit()。
然后进行 DataAdapter 更新。
谢谢 - 希望这对其他人有所帮助。
【讨论】:
以上是关于Winforms Databound Combobox 更新数据但不改变 RowState的主要内容,如果未能解决你的问题,请参考以下文章
Datagridview DatagridviewComboboxColumn 编辑 DataBound
在 DataBound 事件上获取绑定到 ListView 的数据
asp.net 中继器 - 获取行项_DataBound 的值
如果dataBound用于设置选定值,则Kendo UI Dropdownlist客户端过滤器不起作用