C# 移除所有可观察到的集合?

C# 移除所有可观察到的集合?,c#,observablecollection,removeall,C#,Observablecollection,Removeall,我正在寻找Linq方法(如列表的RemoveAll方法),它可以从我的ObservableCollection中删除选定的项 我太新了,无法为自己创建扩展方法。是否有任何方法可以通过Lambda表达式从ObservableCollection中删除项?我不知道有什么方法可以仅删除选定项。但创建扩展方法很简单: public static class ExtensionMethods { public static int Remove<T>( this Obs

我正在寻找Linq方法(如列表的RemoveAll方法),它可以从我的ObservableCollection中删除选定的项


我太新了,无法为自己创建扩展方法。是否有任何方法可以通过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);
}