filtro filtrar wpf linq datagrid filter nscollectionview

wpf - filtro - Filtrar una colección con LINQ vs CollectionView



filtrar datagridview c# (3)

Quiero filtrar un ObservableCollection con un máximo de 3000 elementos en un DataGrid con 6 columnas. El usuario debe poder filtrar en forma de "&&" las 6 columnas.

¿Debo usar LINQ o un CollectionView para ello? LINQ parecía más rápido probando algunas muestras de www. ¿Tienes algún pro / contra?

ACTUALIZAR :

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"); } }


¿Qué tal ambos? Thomas Levesque construyó un contenedor LINQ habilitado alrededor de ICollectionView .

Uso:

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();

Código:

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()); } }

Crédito: http://www.thomaslevesque.com/2011/11/30/wpf-using-linq-to-shape-data-in-a-collectionview/


Para una experiencia interactiva (DataGrid?), Probablemente deberías usar CollectionView. Para una clasificación más orientada a los códigos, LINQ.

Y con un máximo de 3000 elementos, la velocidad no debería ser un factor (mayor) en una UI.


  • Al usar ICollectionView, obtienes notificaciones automáticas de cambio de colección cuando llamas a Refresh. Con LINQ, deberá activar sus propias notificaciones de cambio cuando sea necesario volver a ejecutar el filtro para actualizar la interfaz de usuario. No es difícil, pero requiere un poco más de reflexión que simplemente llamar a Refresh.

  • LINQ es más flexible que el simple filtro de sí / no utilizado por ICollectionView, pero si no está haciendo algo complejo, no hay ninguna ventaja en esa flexibilidad.

  • Como dijo Henk, no debería haber una diferencia de rendimiento notable en la UI.