C# 从 CollectionChanged 事件处理程序中的 ObservableCollection 中删除项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9743420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove an item from an ObservableCollection in a CollectionChanged event handler
提问by ebpa
I'm hoping to be able to reject some items after they have been added to an ObservableCollection. I am not able to subclass the ObservableCollection or use any sort of view, so I seem to be limited to using the one event handler defined (CollectionChanged) to perform a .Remove() on the prohibited items. It's fine if the items exist for the short period between the event being raised and then handled; the items should just not persist in the collection. Calling .Remove() within the CollectionChanged event handler doesn't appear to be allowed. At runtime .NET throws an InvalidOperationException:
我希望能够在将某些项目添加到 ObservableCollection 后拒绝它们。我无法对 ObservableCollection 进行子类化或使用任何类型的视图,因此我似乎仅限于使用定义的一个事件处理程序 (CollectionChanged) 对禁止的项目执行 .Remove() 。如果项目在引发事件和处理事件之间的短时间内存在,那很好;这些项目不应该保留在集合中。似乎不允许在 CollectionChanged 事件处理程序中调用 .Remove() 。在运行时 .NET 抛出一个 InvalidOperationException:
"Cannot change ObservableCollection during a CollectionChanged event."
“无法在 CollectionChanged 事件期间更改 ObservableCollection。”
Personally I think .NET should allow me to. If I create an infinite loop, it's my own darn fault.
我个人认为 .NET 应该允许我这样做。如果我创建了一个无限循环,那是我自己的错。
The code I would like to use would look like:
我想使用的代码如下所示:
myCollection.CollectionChanged += (sender, args) =>
{
if (args.Action == NotifyCollectionChangedAction.Remove)
return;
foreach (var itm in myCollection)
{
if (itm.name == "Fred")
myCollection.Remove(itm);
}
}
I'm not sure what options I have. Using a dispatcher doesn't seem to work. Triggering another event and placing the .Remove call in another handler is the only other option that comes to mind.
我不确定我有哪些选择。使用调度程序似乎不起作用。触发另一个事件并将 .Remove 调用放置在另一个处理程序中是唯一想到的其他选项。
采纳答案by Raj Ranjhan
Check out Common Mistakes using Observable Collection.
使用 Observable Collection查看常见错误。
Having said that, if you still want to go this route - you can spin a new Thread
话虽如此,如果你仍然想走这条路 - 你可以旋转一个新的线程
回答by tam
if you really want to modify a collection you are going to want to iterate through a copy of the collection. its because you are trying to modify the collection in the foreach loop thats causing you grief.
如果您真的想修改一个集合,您将需要遍历该集合的副本。这是因为您试图修改 foreach 循环中的集合,这让您感到悲伤。
example
例子
var copy = new ObservableCollection<YourType>(collection)
foreach(var item in copy)
{
if(item.Name == "Fred")
{
collection.Remove(item);
}
}
that said, I agree with Anurag that you shouldn't be doing this type of thing with an observablecollection and certainly not inside a CollectionChanged Event.
也就是说,我同意 Anurag 的观点,你不应该用 observablecollection 做这种类型的事情,当然也不应该在 CollectionChanged 事件中。
回答by Gilad
use a ToList()in order to iterate over the list.
使用 aToList()来遍历列表。
foreach(var item in collection.ToList())
{
if(item.Name == "Fred")
{
collection.Remove(item);
}
}
回答by Mark
Used this in the oncollectionchanged and it works (WPF and MVVM example):
在 oncollectionchanged 中使用它并且它有效(WPF 和 MVVM 示例):
new System.Threading.Thread(t =>
{
Application.Current.Dispatcher.Invoke((Action)delegate
{
OnHoldMessages.Add(_selectedOnHoldMessage);
RaisePropertyChanged(propertyName: "OnHoldMessages");
});
}).Start();

