2013-03-27 52 views
1

我这样定义CollectionViewSource,但看起来过滤器不工作。CollectionViewSource当SortDescriptions被引入之前,过滤器不工作

CollectionViewSource cvs = new CollectionViewSource(); 

//oc IS AN OBSERVABLE COLLECTION WITH SOME ITEMS OF TYPE MyClass 
cvs.Source = oc;   

//IsSelected IS A bool? PROPERTY OF THE MyClass 
cvs.View.Filter = new Predicate<object>(input=>(input as MyClass).IsSelected == true); 

//Major IS AN string PROPERTY OF THE MyClass 
cvs.SortDescriptions.Add(new SortDescription(
          "Major", ListSortDirection.Ascending)); 

但是我改变了这种方式的代码,一切都解决了!

CollectionViewSource cvs = new CollectionViewSource(); 
cvs.Source = oc;   

cvs.SortDescriptions.Add(new SortDescription(
          "Major", ListSortDirection.Ascending)); 

cvs.View.Filter = new Predicate<object>(input=>(input as MyClass).IsSelected == true); 

任何人都知道吗?

+0

我认为添加排序描述可能会影响View属性(也许它会创建一个新的属性),所以在第一种情况下,您要向视图添加一个过滤器,然后排序描述会有效地更改为新视图? (另外,在你的例子中你有'cvs'和'cvs2',所以它看起来应该不是很重要... – 2013-03-27 18:12:30

+0

你可以快速检查cvs.View是否是排序描述更改后的同一个对象。否则,是不是有一些对CollectionViewSource的调用来使其失效? – 2013-03-27 18:42:50

回答

3

你应该问自己的第一件事是...

为什么我添加分类描述的CollectionViewSource 和过滤器来查看?我不应该将它们都添加到 相同的对象吗?

答案是肯定的!

要直接将过滤器逻辑添加到CollectionViewSource,需要为Filter事件添加事件处理程序。

直接从MSDN,这里有一个例子

listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter); 
private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e) 
{ 
    AuctionItem product = e.Item as AuctionItem; 
    if (product != null) 
    { 
     // Filter out products with price 25 or above 
     if (product.CurrentPrice < 25) 
     { 
      e.Accepted = true; 
     } 
     else 
     { 
      e.Accepted = false; 
     } 
    } 
} 

现在,至于为什么,当你添加排序说明过滤器是越来越删除。

当您将SortDescription添加到CollectionViewSource后面时,它最终会碰到这段代码。

Predicate<object> filter; 
if (FilterHandlersField.GetValue(this) != null) 
{ 
    filter = FilterWrapper; 
} 
else 
{ 
    filter = null; 
} 

if (view.CanFilter) 
{ 
    view.Filter = filter; 
} 

很明显,它覆盖了您在视图上设置的过滤器。

如果您还好奇,这里是source code for CollectionViewSource