2010-10-05 2 views
8

Я хочу отфильтровать ObservableCollection с максимальным количеством 3000 элементов в DataGrid с 6 столбцами. Пользователь должен иметь возможность фильтровать в «& &« все 6 столбцов ».Отфильтровать коллекцию с помощью LINQ vs CollectionView

Должен ли я использовать LINQ или CollectionView для этого? LINQ казался более быстрым, пробуя некоторые образцы www. У вас есть какие-либо про/минусы?

UPDATE:

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

ответ

1

Для интерактивного (DataGrid?) Опыт, который вы должны probabaly использовать CollectionView. Для более упорядоченной по коду сортировки LINQ.

И с максимальным количеством 3000 единиц, скорость не должна быть (основным) фактором в пользовательском интерфейсе.

+0

Я использую CollectionViewSource фильтр только один столбец в данный момент. Вы знаете, почему коллекция обновляется только после того, как я поместил метод .Refresh() в свойство ниже? private string _filterKeywords public string FilterKeywords { get {return _filterKeywords; } set { if (_filterKeywords == значение) return; _filterKeywords = значение; this.RaisePropertyChanged ("FilterKeywords"); MaterialList.Refresh(); } } – Elisabeth

+0

«Вы знаете, почему ...» - Нет, но, может быть, если вы добавите этот код к вопросу, я мог бы его прочитать. –

+0

ok Хенк Я написал весь важный код! доброй ночи ;-) – Elisabeth

3
  • Использование ICollectionView дает вам автоматическую коллекцию измененных уведомлений при вызове Refresh. Используя LINQ, вам необходимо запустить свои собственные уведомления об изменениях, когда необходимо обновить фильтр для обновления пользовательского интерфейса. Не сложно, но требует немного больше мысли, чем просто вызвать Refresh.

  • LINQ более гибкий, чем простая фильтрация да/нет, используемая ICollectionView, но если вы не выполняете что-то сложное, то на эту гибкость нет никакого преимущества.

  • Как заявила Хенк, в пользовательском интерфейсе не должно быть заметных различий в производительности.

1

Как насчет обоих? Томас Левеске создал обертку с поддержкой LINQ около ICollectionView.

Использование:

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

Код:

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

Кредит: http://www.thomaslevesque.com/2011/11/30/wpf-using-linq-to-shape-data-in-a-collectionview/

Смежные вопросы