C# 移除所有可观察到的集合?
我正在寻找Linq方法(如列表的RemoveAll方法),它可以从我的ObservableCollection中删除选定的项C# 移除所有可观察到的集合?,c#,observablecollection,removeall,C#,Observablecollection,Removeall,我正在寻找Linq方法(如列表的RemoveAll方法),它可以从我的ObservableCollection中删除选定的项 我太新了,无法为自己创建扩展方法。是否有任何方法可以通过Lambda表达式从ObservableCollection中删除项?我不知道有什么方法可以仅删除选定项。但创建扩展方法很简单: public static class ExtensionMethods { public static int Remove<T>( this Obs
我太新了,无法为自己创建扩展方法。是否有任何方法可以通过Lambda表达式从ObservableCollection中删除项?我不知道有什么方法可以仅删除选定项。但创建扩展方法很简单:
public static class ExtensionMethods
{
public static int Remove<T>(
this ObservableCollection<T> coll, Func<T, bool> condition)
{
var itemsToRemove = coll.Where(condition).ToList();
foreach (var itemToRemove in itemsToRemove)
{
coll.Remove(itemToRemove);
}
return itemsToRemove.Count;
}
}
无法将表达式传递给ObservaleCollection以删除匹配项,这与泛型列表的方式相同。ObservableCollection一次添加和删除一项
为此,您必须创建自己的INotifyCollectionChanged实现,或者您提到的创建扩展方法。向后迭代应该比像Daniel Hilgarth那样创建临时集合更有效
公共静态类ObservableCollectionExtensions
{
public static void RemoveAll(此ObservableCollection集合,
Func条件)
{
对于(int i=collection.Count-1;i>=0;i--)
{
if(条件(集合[i]))
{
收集、移除(i);
}
}
}
}
这里提出的每个使用例程逐个删除项的解决方案都有一个故障。假设您在可观察的集合中有许多项,比如说10000项。然后,您希望删除满足某些条件的项目
如果您使用并调用:c.Remove(x=>x.IsSelected)代码>例如,有3000个项目要删除,建议的解决方案将通知每个项目的删除。这是因为Remove(item)
的内部实现会通知该更改。在拆除过程中,3000件物品中的每一件都需要这样做
因此,我创建了ObservableCollection的后代,并添加了新方法RemoveAll(谓词)
一行程序的这种实现怎么样
observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))
--编辑--
对不起,是的,你需要中间的一个TristIf()来迫使上半部分进行评估,因为LINQ默认是懒惰的评估。
< P>这是我的扩展方法解决方案的版本,这只是对被接受的答案的一个细微的变化,但其优点是,返回的计数基于已确认从集合中删除的项目:
public static class ObservableCollectionExtensionMethods
{
/// <summary>
/// Extends ObservableCollection adding a RemoveAll method to remove elements based on a boolean condition function
/// </summary>
/// <typeparam name="T">The type contained by the collection</typeparam>
/// <param name="observableCollection">The ObservableCollection</param>
/// <param name="condition">A function that evaluates to true for elements that should be removed</param>
/// <returns>The number of elements removed</returns>
public static int RemoveAll<T>(this ObservableCollection<T> observableCollection, Func<T, bool> condition)
{
// Find all elements satisfying the condition, i.e. that will be removed
var toRemove = observableCollection
.Where(condition)
.ToList();
// Remove the elements from the original collection, using the Count method to iterate through the list,
// incrementing the count whenever there's a successful removal
return toRemove.Count(observableCollection.Remove);
}
}
公共静态类ObservableCollectionExtensionMethods
{
///
///扩展ObservableCollection,添加RemoveAll方法以基于布尔条件函数删除元素
///
///集合包含的类型
///可观测集合
///对于应删除的元素,其计算结果为true的函数
///删除的元素数
公共静态int RemoveAll(此ObservableCollection ObservableCollection,Func条件)
{
//找到满足条件的所有元素,即将被删除的元素
var toRemove=可观察到的收集
.何处(条件)
.ToList();
//使用Count方法迭代列表,从原始集合中移除元素,
//每当成功删除时递增计数
返回到Remove.Count(observableCollection.Remove);
}
}
ObservableCollection\u appVariables=new-new-ObservableCollection();
var temp=appepository.AppVariables.Where(i=>i.IsChecked==true).OrderByDescending(k=>k.Index);
foreach(温度中的变量i)
{
AppRepository.AppVariables.RemoveAt(i.Index);
}
是否有必要在return语句之前添加itemsToRemove.Clear()?@JoanComasFdz:No.itemsToRemove
将由垃圾收集器声明。@ShaktiPrakashSingh:很好。返回集合表示原始集合未更改,并且已创建新集合。正如你所指出的,情况并非如此。此外,List
上的方法返回计数,因此最好遵循该方法。我相应地改变了答案。谢谢你的评论。@DanielHilgarth非常感谢,你让我开心@DanielHilgarth哈哈,这是公司代码库内部的一个扩展。已删除的comment.WPF注意:当将此与ItemsControl一起使用时,当使用NotifyCollectionChangedAction.Reset时,控件将在内部调用Clear;在我的特定用例中,当我对新添加的项目进行动画时,这导致了不希望出现的副作用~在一个正在测试的真实世界应用程序中,我发现这实际上比临时采集慢-平均时间为67毫秒,峰值为152毫秒,而临时采集的平均时间为55毫秒,峰值为93毫秒。请记住,这只适用于一个小集合。我尝试了这个集合,但最终出现错误:“集合已修改;枚举操作可能无法执行。”我发现这是一个非常简单/优雅的解决方案。在投票支持率更高的较长解决方案中,这有什么缺点吗?也许是可读性。第一次阅读时不清楚它在做什么,而公认的答案将它分成两个更明显的部分。我建议使用List.ForEach
而不是All
。我认为All(…)
是添加ToList()
之前的产物。在一个正在测试的真实应用程序中,我发现这确实比临时采集快-平均时间为44毫秒,峰值为62毫秒,而临时采集的平均时间为55毫秒,峰值为93毫秒。请尝试添加一些关于您答案的简要信息。相关
[Serializable]
public class ObservableCollectionExt<T> : ObservableCollection<T>
{
public void RemoveAll(Predicate<T> predicate)
{
CheckReentrancy();
List<T> itemsToRemove = Items.Where(x => predicate(x)).ToList();
itemsToRemove.ForEach(item => Items.Remove(item));
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
}
OnPropertyChanged(new PropertyChangedEventArgs("Count"));
OnPropertyChanged(new PropertyChangedEventArgs("Item[]"));
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
observableCollection.Where(l => l.type == invalid).ToList().All(i => observableCollection.Remove(i))
public static class ObservableCollectionExtensionMethods
{
/// <summary>
/// Extends ObservableCollection adding a RemoveAll method to remove elements based on a boolean condition function
/// </summary>
/// <typeparam name="T">The type contained by the collection</typeparam>
/// <param name="observableCollection">The ObservableCollection</param>
/// <param name="condition">A function that evaluates to true for elements that should be removed</param>
/// <returns>The number of elements removed</returns>
public static int RemoveAll<T>(this ObservableCollection<T> observableCollection, Func<T, bool> condition)
{
// Find all elements satisfying the condition, i.e. that will be removed
var toRemove = observableCollection
.Where(condition)
.ToList();
// Remove the elements from the original collection, using the Count method to iterate through the list,
// incrementing the count whenever there's a successful removal
return toRemove.Count(observableCollection.Remove);
}
}
ObservableCollection<AppVariable<G>> _appVariables = new new ObservableCollection<AppVariable<G>>();
var temp = AppRepository.AppVariables.Where(i => i.IsChecked == true).OrderByDescending(k=>k.Index);
foreach (var i in temp)
{
AppRepository.AppVariables.RemoveAt(i.Index);
}