Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 使用LINQ vs CollectionView筛选集合_Wpf_Linq_Datagrid_Filter_Nscollectionview - Fatal编程技术网

Wpf 使用LINQ vs CollectionView筛选集合

Wpf 使用LINQ vs CollectionView筛选集合,wpf,linq,datagrid,filter,nscollectionview,Wpf,Linq,Datagrid,Filter,Nscollectionview,我想在一个有6列的DataGrid中过滤一个最多3000项的ObservableCollection。用户应该能够以“&&”的方式筛选所有6列 我应该使用LINQ还是CollectionView?LINQ似乎更快地尝试了一些www样本。你有什么赞成/反对意见吗 更新: private ObservableCollection<Material> _materialList; private ObservableCollection<Material> _m

我想在一个有6列的DataGrid中过滤一个最多3000项的ObservableCollection。用户应该能够以“&&”的方式筛选所有6列

我应该使用LINQ还是CollectionView?LINQ似乎更快地尝试了一些www样本。你有什么赞成/反对意见吗

更新

private ObservableCollection<Material> _materialList;
        private ObservableCollection<Material> _materialListInternal;

        public MaterialBrowserListViewModel()
        {           
              _materialListInternal = new ObservableCollection<Material>();          

            for (int i = 0; i < 2222; i++)
            {
                var mat = new Material()
                {
                    Schoolday = DateTime.Now.Date,
                    Period = i,
                    DocumentName = "Excel Sheet" + i,
                    Keywords = "financial budget report",
                    SchoolclassCode = "1",
                };
                _materialListInternal.Add(mat);
                var mat1 = new Material()
                {
                    Schoolday = DateTime.Now.Date,
                    Period = i,
                    DocumentName = "Word Doc" + i,
                    Keywords = "Economical staticstics report",
                    SchoolclassCode = "2",
                };
                _materialListInternal.Add(mat1);
            }

            MaterialList = CollectionViewSource.GetDefaultView(MaterialListInternal);
            MaterialList.Filter = new Predicate<object>(ContainsInFilter); 
        }      

        public bool ContainsInFilter(object item)
        {
            if (String.IsNullOrEmpty(FilterKeywords))
                return true;   

            Material material = item as Material;
            if (DocumentHelper.ContainsCaseInsensitive(material.Keywords,FilterKeywords,StringComparison.CurrentCultureIgnoreCase))        
                return true;          
            else          
                return false;                     
        }

        private string _filterKeywords;
        public string FilterKeywords
        {
            get { return _filterKeywords; }
            set
            {
                if (_filterKeywords == value)
                    return;

                _filterKeywords = value;
                this.RaisePropertyChanged("FilterKeywords");
                MaterialList.Refresh();               
            }
        }

        public ICollectionView MaterialList { get; set; }

        public ObservableCollection<Material> MaterialListInternal
        {
            get { return _materialListInternal; }
            set
            {
                _materialListInternal = value;
                this.RaisePropertyChanged("MaterialList");
            }
        } 
private observeCollection\u materialList;
私人可观察收集材料内部;
公共材料浏览器列表视图模型()
{           
_材料内部=新的可观察收集();
对于(int i=0;i<2222;i++)
{
var mat=新材料()
{
Schoolday=DateTime.Now.Date,
周期=i,
DocumentName=“Excel工作表”+i,
关键词=“财务预算报告”,
SchoolclassCode=“1”,
};
_材料内部添加(垫);
var mat1=新材料()
{
Schoolday=DateTime.Now.Date,
周期=i,
DocumentName=“Word Doc”+i,
关键词=“经济统计报告”,
SchoolclassCode=“2”,
};
_材料内部添加(材料1);
}
MaterialList=CollectionViewSource.GetDefaultView(MaterialListInternal);
MaterialList.Filter=新谓词(containsFilter);
}      
公共bool containsFilter(对象项)
{
if(String.IsNullOrEmpty(FilterKeywords))
返回true;
材料=作为材料的项目;
if(DocumentHelper.ContainsCaseInsensitive(material.Keywords、FilterKeywords、StringComparison.CurrentCultureIgnorCase))
返回true;
其他的
返回false;
}
私有字符串\u过滤器关键字;
公共字符串筛选器关键字
{
获取{return\u filterKeywords;}
设置
{
if(_filterKeywords==值)
返回;
_filterKeywords=值;
this.RaisePropertyChanged(“FilterKeywords”);
材料列表刷新();
}
}
公共ICollectionView材质列表{get;set;}
公共可见收集材料内部
{
获取{return\u materialListInternal;}
设置
{
_材料内部=数值;
本.RaisePropertyChanged(“材料专家”);
}
} 
对于交互式(DataGrid?)体验,您可能应该使用CollectionView。对于更面向代码的排序,LINQ

对于最多3000个项目,速度不应该是UI中的一个(主要)因素。

  • 使用ICollectionView可以在调用Refresh时自动发出集合更改通知。使用LINQ,当需要重新运行过滤器以更新UI时,您需要触发自己的更改通知。不难,但需要比调用Refresh更多的思考

  • LINQ比ICollectionView使用的简单的是/否过滤更灵活,但是如果您不做复杂的事情,那么这种灵活性实际上没有任何优势

  • 正如Henk所说,UI中不应该有明显的性能差异


两者如何?Thomas Levesque围绕
ICollectionView
构建了一个启用LINQ的包装器

用法:

IEnumerable<Person> people;

// Using query comprehension
var query =
    from p in people.ShapeView()
    where p.Age >= 18
    orderby p.LastName, p.FirstName
    group p by p.Country;

query.Apply();

// Using extension methods
people.ShapeView()
      .Where(p => p.Age >= 18)
      .OrderBy(p => p.LastName)
      .ThenBy(p => p.FirstName)
      .Apply();
i无数人;
//使用查询理解
变量查询=
来自people.ShapeView()中的p
其中p.年龄>=18
orderby p.LastName,p.FirstName
p组按p.国家分组;
query.Apply();
//使用扩展方法
people.ShapeView()
.其中(p=>p.年龄>=18)
.OrderBy(p=>p.LastName)
.ThenBy(p=>p.FirstName)
.Apply();
代码:

公共静态类集合ViewShaper
{
公共静态集合ViewShapper ShapeView(此IEnumerable源)
{
var view=CollectionViewSource.GetDefaultView(源);
返回新集合ViewShaper(视图);
}
公共静态集合视图形状(此ICollectionView视图)
{
返回新集合ViewShaper(视图);
}
}
公共类集合ViewShaper
{
私有只读ICollectionView\u视图;
私有谓词过滤器;
私有只读列表_sortddescriptions=new List();
私有只读列表_groupDescriptions=新列表();
公共集合视图形状器(ICollectionView视图)
{
如果(视图==null)
抛出新的异常(“视图”);
_视图=视图;
_filter=view.filter;
_sortDescriptions=view.sortDescriptions.ToList();
_groupDescriptions=view.groupDescriptions.ToList();
}
公开无效申请()
{
使用(_view.DeferRefresh())
{
_view.Filter=\u Filter;
_view.SortDescriptions.Clear();
foreach(分类说明中的var s)
{
_view.SortDescriptions.Add(s);
}
_view.GroupDescriptions.Clear();
foreach(组描述中的变量g)
{
_view.GroupDescriptions.Add(g);
}
}
}
公共集合ViewShaper ClearGrouping()
{
_groupDescriptions.Clear();
归还这个;
}
公共集合ViewShaper ClearSort()
{
_sortDescriptions.Clear();
归还这个;
}
公共集合ViewShaper ClearFilter()
{
_filter=null;
归还这个;
}
公共集合ViewShaper ClearAll()
{
_filter=null;
_sortDescriptions.Clear();
_groupDescriptions.Clear();
public static class CollectionViewShaper
{
    public static CollectionViewShaper<TSource> ShapeView<TSource>(this IEnumerable<TSource> source)
    {
        var view = CollectionViewSource.GetDefaultView(source);
        return new CollectionViewShaper<TSource>(view);
    }

    public static CollectionViewShaper<TSource> Shape<TSource>(this ICollectionView view)
    {
        return new CollectionViewShaper<TSource>(view);
    }
}

public class CollectionViewShaper<TSource>
{
    private readonly ICollectionView _view;
    private Predicate<object> _filter;
    private readonly List<SortDescription> _sortDescriptions = new List<SortDescription>();
    private readonly List<GroupDescription> _groupDescriptions = new List<GroupDescription>();

    public CollectionViewShaper(ICollectionView view)
    {
        if (view == null)
            throw new ArgumentNullException("view");
        _view = view;
        _filter = view.Filter;
        _sortDescriptions = view.SortDescriptions.ToList();
        _groupDescriptions = view.GroupDescriptions.ToList();
    }

    public void Apply()
    {
        using (_view.DeferRefresh())
        {
            _view.Filter = _filter;
            _view.SortDescriptions.Clear();
            foreach (var s in _sortDescriptions)
            {
                _view.SortDescriptions.Add(s);
            }
            _view.GroupDescriptions.Clear();
            foreach (var g in _groupDescriptions)
            {
                _view.GroupDescriptions.Add(g);
            }
        }
    }

    public CollectionViewShaper<TSource> ClearGrouping()
    {
        _groupDescriptions.Clear();
        return this;
    }

    public CollectionViewShaper<TSource> ClearSort()
    {
        _sortDescriptions.Clear();
        return this;
    }

    public CollectionViewShaper<TSource> ClearFilter()
    {
        _filter = null;
        return this;
    }

    public CollectionViewShaper<TSource> ClearAll()
    {
        _filter = null;
        _sortDescriptions.Clear();
        _groupDescriptions.Clear();
        return this;
    }

    public CollectionViewShaper<TSource> Where(Func<TSource, bool> predicate)
    {
        _filter = o => predicate((TSource)o);
        return this;
    }

    public CollectionViewShaper<TSource> OrderBy<TKey>(Expression<Func<TSource, TKey>> keySelector)
    {
        return OrderBy(keySelector, true, ListSortDirection.Ascending);
    }

    public CollectionViewShaper<TSource> OrderByDescending<TKey>(Expression<Func<TSource, TKey>> keySelector)
    {
        return OrderBy(keySelector, true, ListSortDirection.Descending);
    }

    public CollectionViewShaper<TSource> ThenBy<TKey>(Expression<Func<TSource, TKey>> keySelector)
    {
        return OrderBy(keySelector, false, ListSortDirection.Ascending);
    }

    public CollectionViewShaper<TSource> ThenByDescending<TKey>(Expression<Func<TSource, TKey>> keySelector)
    {
        return OrderBy(keySelector, false, ListSortDirection.Descending);
    }

    private CollectionViewShaper<TSource> OrderBy<TKey>(Expression<Func<TSource, TKey>> keySelector, bool clear, ListSortDirection direction)
    {
        string path = GetPropertyPath(keySelector.Body);
        if (clear)
            _sortDescriptions.Clear();
        _sortDescriptions.Add(new SortDescription(path, direction));
        return this;
    }

    public CollectionViewShaper<TSource> GroupBy<TKey>(Expression<Func<TSource, TKey>> keySelector)
    {
        string path = GetPropertyPath(keySelector.Body);
        _groupDescriptions.Add(new PropertyGroupDescription(path));
        return this;
    }

    private static string GetPropertyPath(Expression expression)
    {
        var names = new Stack<string>();
        var expr = expression;
        while (expr != null && !(expr is ParameterExpression) && !(expr is ConstantExpression))
        {
            var memberExpr = expr as MemberExpression;
            if (memberExpr == null)
                throw new ArgumentException("The selector body must contain only property or field access expressions");
            names.Push(memberExpr.Member.Name);
            expr = memberExpr.Expression;
        }
        return String.Join(".", names.ToArray());
    }
}