WPF CollectionChanged 事件 OldItems.Count
WPF CollectionChanged Event OldItems.Count
我有一个 ObservableCollection 并附加到 CollectionChanged 事件:
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
for (int i = 0; i < e.NewItems.Count; i++)
{
int id = -1 * i;
DocumentWatchList d = (DocumentWatchList)e.NewItems[i];
d.UID = id;
_dataDc.DocumentWatchLists.InsertOnSubmit(d);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
for (int i = 0; i < e.OldItems.Count; i++)
{
DocumentWatchList d = (DocumentWatchList)e.OldItems[i];
_dataDc.DocumentWatchLists.DeleteOnSubmit(d);
}
}
_dataDc.SubmitChanges();
}
我的集合绑定到数据网格,并按预期调用了视图模型代码(上方)。当我 select 多行并点击删除时,我希望 OldItems 集合将包含我 selected (n) 的行数。然而,实际发生的是该事件被调用 n 次,每次 OldItems 集合计数为 1。那么在什么情况下 OldItems 集合包含超过 1 个项目?这种行为是来自数据网格控件,还是 ObservableCollection.CollectionChanged 的工作方式?
出于某种原因,ObservableCollection 不支持包含多个项目的 NotifyCollectionChanged 事件。
你可以这样做:
OnCollectionChanged(
new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, singleItem));
但不是这个:(你会得到一个 NotSupportedException
)
OnCollectionChanged(
new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, multipleItems));
我想不出 e.OldItems.Count 会大于 0 的任何情况。
Here 是一篇关于它的好文章,其中有人出于性能目的实际实现了对多个项目的处理。
如果您看一下 observable 集合为您提供的界面,您就已经知道您将获得什么:
https://msdn.microsoft.com/en-us/library/ms668604%28v=vs.110%29.aspx
基本上它不提供任何方式一次插入或删除多个项目。所以这实际上意味着你可以清除整个集合,但是如果你需要说删除 2 个项目而集合中有 6 个项目,你将不得不一个一个地删除它们。这就是数据网格在您的情况下将执行的操作,但假设您要实现自己的数据网格,您将被迫以相同的方式执行此操作。
为了使答案完整,我必须补充一点,有一种方法可以获得已删除列表中的多个项目,但只能通过清除集合。
替换集合中的项目也是可能的,通过使用索引运算符,您甚至可以用项目本身替换项目。我尝试了这个并且有效,在这种情况下,您将在删除的集合和插入的集合中获得相同的项目,但也会在此处逐一获得。
您当然可以创建自己的可观察集合实现来解决这些问题。但我认为您也需要数据网格的不同实现,它将使用您自定义的新批量插入或批量删除操作。
我有一个 ObservableCollection 并附加到 CollectionChanged 事件:
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
for (int i = 0; i < e.NewItems.Count; i++)
{
int id = -1 * i;
DocumentWatchList d = (DocumentWatchList)e.NewItems[i];
d.UID = id;
_dataDc.DocumentWatchLists.InsertOnSubmit(d);
}
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
for (int i = 0; i < e.OldItems.Count; i++)
{
DocumentWatchList d = (DocumentWatchList)e.OldItems[i];
_dataDc.DocumentWatchLists.DeleteOnSubmit(d);
}
}
_dataDc.SubmitChanges();
}
我的集合绑定到数据网格,并按预期调用了视图模型代码(上方)。当我 select 多行并点击删除时,我希望 OldItems 集合将包含我 selected (n) 的行数。然而,实际发生的是该事件被调用 n 次,每次 OldItems 集合计数为 1。那么在什么情况下 OldItems 集合包含超过 1 个项目?这种行为是来自数据网格控件,还是 ObservableCollection.CollectionChanged 的工作方式?
出于某种原因,ObservableCollection 不支持包含多个项目的 NotifyCollectionChanged 事件。
你可以这样做:
OnCollectionChanged(
new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, singleItem));
但不是这个:(你会得到一个 NotSupportedException
)
OnCollectionChanged(
new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, multipleItems));
我想不出 e.OldItems.Count 会大于 0 的任何情况。
Here 是一篇关于它的好文章,其中有人出于性能目的实际实现了对多个项目的处理。
如果您看一下 observable 集合为您提供的界面,您就已经知道您将获得什么:
https://msdn.microsoft.com/en-us/library/ms668604%28v=vs.110%29.aspx
基本上它不提供任何方式一次插入或删除多个项目。所以这实际上意味着你可以清除整个集合,但是如果你需要说删除 2 个项目而集合中有 6 个项目,你将不得不一个一个地删除它们。这就是数据网格在您的情况下将执行的操作,但假设您要实现自己的数据网格,您将被迫以相同的方式执行此操作。
为了使答案完整,我必须补充一点,有一种方法可以获得已删除列表中的多个项目,但只能通过清除集合。
替换集合中的项目也是可能的,通过使用索引运算符,您甚至可以用项目本身替换项目。我尝试了这个并且有效,在这种情况下,您将在删除的集合和插入的集合中获得相同的项目,但也会在此处逐一获得。
您当然可以创建自己的可观察集合实现来解决这些问题。但我认为您也需要数据网格的不同实现,它将使用您自定义的新批量插入或批量删除操作。