我有两个按钮 - 取消和添加,在网格视图中添加一个新行,并且每次单击它时,都会在上下文中添加一条新记录,该记录连接到绑定源,该源设置为网格视图的数据源。
因此,如果我有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。
答案 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;
}
在上面的示例中,我们仅使用未保存的元素迭代临时集合,并从context
和bindingSource1
中删除其中的每一个。