2010-10-05 17 views
8

के साथ एक संग्रह फ़िल्टर करें मैं 6 कॉलम के साथ डेटाग्रिड में अधिकतम 3000 आइटम के साथ एक ऑब्जर्जेबल कोलेक्शन फ़िल्टर करना चाहता हूं। उपयोगकर्ता को "& &" में फ़िल्टर करने में सक्षम होना चाहिए -वे सभी 6 कॉलम।LINQ बनाम संग्रह दृश्य

क्या मुझे इसके लिए 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"); 
      } 
     } 

उत्तर

1

एक इंटरैक्टिव (डेटा ग्रिड?) अनुभव आप probabaly CollectionView का उपयोग करना चाहिए के लिए। अधिक कोड-उन्मुख सॉर्टिंग के लिए, LINQ।

और अधिकतम 3000 वस्तुओं के साथ, यूआई में गति (प्रमुख) कारक नहीं होना चाहिए।

+0

मैं एक CollectionViewSource फिल्टर इस समय केवल एक कॉलम का उपयोग कर रहा हूँ। क्या आप जानते हैं कि संग्रह केवल तभी अपडेट किया जाता है जब मैंने नीचे की संपत्ति में .efresh() विधि डाली? निजी स्ट्रिंग _filterKeywords सार्वजनिक स्ट्रिंग फ़िल्टरकेड्स { {वापसी _filterKeywords प्राप्त करें; } सेट { अगर (_filterKeywords == मान) वापसी; _filterKeywords = value; यह। रायसप्रॉपर्टी चेंज ("फ़िल्टरकेड्स"); MaterialList.Refresh(); } } – Elisabeth

+0

"क्या आप जानते हैं क्यों ..." - नहीं, लेकिन शायद अगर आप उस कोड को प्रश्न में जोड़ते हैं तो मैं इसे पढ़ सकता हूं। –

+0

ठीक हैनक मैंने सभी महत्वपूर्ण कोड पोस्ट किए! शुभ रात्रि ;-) – Elisabeth

3
  • ICollectionView का उपयोग करके आप स्वत: संग्रह देता सूचनाएं बदल गया जब आप ताज़ा कहते हैं। LINQ का उपयोग करते समय आपको यूआई को अपडेट करने के लिए फिर से चलाने की आवश्यकता होने पर आपको अपनी खुद की परिवर्तन अधिसूचनाओं को आग लगाना होगा। मुश्किल नहीं है, लेकिन केवल ताज़ा करने के बजाय थोड़ा और विचार की आवश्यकता है।

  • LINQ अधिक लचीला है कि आईसीओलेक्शन व्यू द्वारा उपयोग की जाने वाली सरल हां/नहीं फ़िल्टरिंग, लेकिन यदि आप कुछ जटिल नहीं कर रहे हैं तो उस लचीलेपन के लिए वास्तव में कोई फायदा नहीं है।

  • जैसा कि हेनक ने कहा, यूआई में उल्लेखनीय प्रदर्शन अंतर नहीं होना चाहिए।

1

दोनों के बारे में कैसे? थॉमस लेवेस्क ने ICollectionView के आसपास एक LINQ- सक्षम wrapper बनाया।

उपयोग:

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/

संबंधित मुद्दे