C# IEnumerable到ObservableCollection失败
我有一个泛型类,用于对ObservableCollections执行一些过滤操作—一种小型自定义分页机制C# IEnumerable到ObservableCollection失败,c#,mvvm,ienumerable,observablecollection,C#,Mvvm,Ienumerable,Observablecollection,我有一个泛型类,用于对ObservableCollections执行一些过滤操作—一种小型自定义分页机制 public class Paginate<T> : INotifyPropertyChanged { public readonly ObservableCollection<T> all_data; public ObservableCollection<T> filtered_data; public Paginat
public class Paginate<T> : INotifyPropertyChanged
{
public readonly ObservableCollection<T> all_data;
public ObservableCollection<T> filtered_data;
public Paginate(ObservableCollection<T> _data)
{
all_data = _data;
filtered_data = all_data;
}
public ObservableCollection<T> Filter(Func<T, bool> obj)
{
//Filter collection
//This takes about 10ms to finish - no errors at all
//var test = all_data.Where(obj).ToList();
//This doesn't finish at all, consuming a lot of memory
filtered_data = all_data.Where(obj).ToObservableCollection();
//...
return filtered_data;
}
}
公共类分页:INotifyPropertyChanged
{
公共只读可观察收集所有_数据;
公共可观测收集过滤的数据;
公共分页(可观测收集数据)
{
所有_数据=_数据;
过滤的_数据=所有_数据;
}
公共可观测收集过滤器(Func obj)
{
//过滤器集合
//这大约需要10毫秒才能完成-完全没有错误
//var测试=所有数据,其中(obj).ToList();
//这根本没有结束,消耗了大量内存
过滤的_数据=所有_数据。其中(obj).ToObservableCollection();
//...
返回过滤后的数据;
}
}
我的问题是在过滤器方法中,将IEnumerable转换为ObservableCollection并没有完成。然而,当Linq结果是少量记录时,它确实会正确完成。以下是我如何调用ViewModel中的所有内容(按钮的命令):
private void Filter\u Execute(对象参数)
{
//测试数据是ObservableCollection,_paginate是paginate类的实例
Test_data=_paginate.Filter(Filter_data);
//...
}
公共布尔过滤器_数据(对象obj)
{
//过滤逻辑
如果(obj是学生)
{
return((string.IsNullOrEmpty(Name)?true:student.Name==Name)
&(string.IsNullOrEmpty(姓氏)?true:student.姓氏==姓氏)
&(string.IsNullOrEmpty(Age)?true:student.Age==Convert.ToInt16(Age))
);
}
返回false;
}
以及我将IEnumerable转换为ObservableCollection的扩展方法:
public static ObservableCollection<T> ToObservableCollection<T> (this IEnumerable<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return new ObservableCollection<T>(source);
}
公共静态ObservableCollection ToObservableCollection(此IEnumerable源)
{
if(source==null)
{
抛出新的ArgumentNullException(“源”);
}
返回新的ObservableCollection(源);
}
那么我做错了什么
更新
我的问题在于绑定到DataGrid时的UI端。显然,当Linq结果超过您在UI中显示的项目数时,您不能将属性ScrollViewer.CanContentScroll设置为False。这不知何故导致了无法停止的巨大内存泄漏
我现在正在研究一个解决方案。(旁白:您可能想使用
&&
而不是&
)我看不到任何明显的东西——这一切看起来都相当合理。你需要找出它在哪里花费时间——探查器是最好的方法,但是随机破坏调试器并查看执行的是哪一行是一种快速而肮脏的方式来获得第一感觉在这段代码中没有IObservable
——这完全是一个骗局ObservableCollection
与IObservable
没有任何关系您的代码中的所有数据肯定是ObservableCollection
吗?这听起来很像一个查询提供者必须将数据库查询的所有结果具体化才能运行该过滤器,而这需要时间和内存。这会导致您看到的症状,但1)这也会影响.ToList()
以及.ToObservableCollection()
,2)只有当所有的数据都是一个IQueryable
且没有任何区别时才会起作用--过滤的数据
是一个字段,而不是一个属性,所以你不能和它绑定。它可以绑定到的最早点是在Filter
返回之后,也就是在您告诉我们此问题发生之后
public static ObservableCollection<T> ToObservableCollection<T> (this IEnumerable<T> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return new ObservableCollection<T>(source);
}