2013-03-27 34 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