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,如果您尝试添加第二个,则会出现异常。顺便说一句,始终设置DisplayMemberValueMember(按此顺序)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客户端过滤器不起作用

Angular 2 Grid dataBound 事件的 Kendo UI

WPF DataBound 树视图展开/折叠