如何取消bindingSource中的所有更改?

时间:2014-11-06 09:49:42

标签: c# winforms bindingsource

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

因此,如果我有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。

2 个答案:

答案 0 :(得分:3)

您的问题只是从您正在通过的列表中删除项目。如果从BindingSources列表中删除某个项目,则它前面的项目将被移回一个索引,这意味着您将跳过已重新定位到从中删除该项目的索引的项目。

最简单的解决方案是将计数器的增量移动到else块,这样只有当项目 NOT 被移除时,计数器才会递增,否则您希望再次检查相同的索引,现在,新项目占据了这个指数。

<强>加成-信息: 我建议您查看BindingList,并考虑将其用作BindingSource的数据源,而不是普通的List<T>。将BindingList与bindingsource结合使用的主要优点是bindinglist在列表更改时触发事件,这些事件由bindingsource订阅。这意味着你只需要担心&#34;关于对BindingList实例进行更改 - 绑定源拾取更改并使用bindingsource作为数据源反映在控件中。

<强>超兆累积奖金-信息: 如果您希望取消对BindingSource中的单个项目所做的更改(可在Current属性中找到),则可以使用方法CancelEdit。但是为了对此产生任何影响,bindingsource中包含的对象类型需要实现IEditableObject interface

答案 1 :(得分:1)

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是什么,但是使用此方法无法更新它,但您可以采用混合方式与之前的操作混合。您可以迭代临时集合而不是直接迭代trhough 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中删除其中的每一个。