【问题标题】:How to cancel all changes in a bindingSource?如何取消 bindingSource 中的所有更改?
【发布时间】:2014-11-06 09:49:42
【问题描述】:

我有两个按钮 - 取消和添加,分别在网格视图中添加新行,每次单击它时,都会将新记录添加到上下文中,该上下文连接到绑定源,绑定源设置为网格视图的数据源。

因此,如果我有 2 行并添加 8 行(例如),当我单击取消时,它应该只清除未保存的行并将它们再次保留为两行。

问题是它只取消了其中的 4 个(我可以在我的代码中看到问题,但我找不到解决方法)。

这是我的简单代码,目前还不行:

try
        {
            DialogResult dialogResult = MessageBox.Show("Do you want to cancel all unsaved changes?", "Cancel all unsaved changes", MessageBoxButtons.YesNo);
            if (dialogResult == DialogResult.Yes)
            {
                for (var i = 0; i < bindingSource1.Count; i++)
                {
                    var f = bindingSource1[i] as MyConfiguration;

                    if (f.MyConfigurationId == 0)
                    {
                        context.RemoveMyConfiguration(f);
                        bindingSource1.Remove(f);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }

问题是我遍历绑定源并同时删除元素并且它得到更新,所以在某些时候它可以看到它已经循环了整个集合。

正确的方法是什么?我应该遍历网格中的行吗?

编辑:对此我深表歉意,它是 WinForms。 BindingSource的数据源是来自数据库的List。我正在使用实体框架 4.0。

【问题讨论】:

  • 当您说“网格视图”时,您是指 ASP.NET GridView 还是实际上是 WinForms DataGridViewBindingSource 的数据源是什么?
  • 对此我深表歉意,它是 WinForms。 BindingSource 的数据源是来自数据库的 List。我正在使用实体框架 4.0。
  • @jmcilhinney 其实我用的是 DevExpress 的网格视图,但我猜它和DataGridView的原理是一样的

标签: c# winforms bindingsource


【解决方案1】:

您的问题只是您从正在迭代的列表中删除了项目。如果您从 BindingSources 列表中删除一个项目,它前面的项目将向后移动一个索引,这意味着您将跳过已重新定位到您从中删除项目的索引的项目。

最简单的解决方案是将计数器的增量移动到 else 块中,这样计数器仅在 NOT 删除项目时才增加,否则您希望再次检查相同的索引,因为一个新项目现在占据了这个索引。

奖励信息: 我建议看一下BindingList,并考虑将其用作BindingSource 的数据源,而不是普通的List&lt;T&gt;。将 BindingList 与 bindingsource 结合使用的主要优点是,当列表更改时,bindinglist 会触发事件,这些事件由 bindingsource 订阅。这意味着您只需“担心”对 BindingList 实例进行更改 - 更改由 bindingsource 获取并反映在使用 bindingsource 作为数据源的控件中。

超级大奖信息: 如果您希望取消对 BindingSource 中的单个项目(在 Current 属性中找到)所做的更改,您可以使用方法 CancelEdit。但是要使绑定源中包含的对象类型产生任何效果,需要实现IEditableObject interface

【讨论】:

    【解决方案2】:

    来点 LINQ 怎么样?我不知道 bindingSource1 是什么类型,但我猜这是一个实现 IEnumerable 的集合,因此 LINQ 扩展方法可用。

    try
            {
                DialogResult dialogResult = MessageBox.Show("Do you want to cancel all unsaved changes?", "Cancel all unsaved changes", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    bindingSource1 = bindingSource1.Where(bs => (bs as MyConfiguration).MyConfigurationId != 0);//.ToList(); if needed
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
    

    我不知道context 是什么,但使用此方法您无法更新它,但您可以做一个解决方法,将您的方式与之前的操作混合。您可以迭代一个临时集合,而不是直接通过bindingSource1 进行迭代,如下所示:

    try
            {
                DialogResult dialogResult = MessageBox.Show("Do you want to cancel all unsaved changes?", "Cancel all unsaved changes", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    foreach (MyConfiguration f in bindingSource1.Select(bs => bs as MyConfiguration).Where(bs => bs.MyConfigurationId == 0))
                    {
                            context.RemoveMyConfiguration(f);
                            bindingSource1.Remove(f);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
    

    在上面的例子中,我们只遍历一个带有未保存元素的临时集合,并从contextbindingSource1 中删除它们中的每一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-01
      • 2021-07-06
      • 2023-03-28
      • 2023-03-31
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      相关资源
      最近更新 更多