2012-10-05 56 views
2

我有一個ListView綁定到一個CollectionViewSource。我跟着這篇文章(被許多人引用)進行多重過濾:http://www.zagstudio.com/blog/456#.UG8r6E1lWLEWPF多個過濾器CollectionViewSource,第一個過濾器添加工作正常,第二個過濾器添加不

我有兩個複選框設置爲測試,除了添加一個過濾器什麼也不做。每當我點擊任何一個,過濾器被添加到CollectionViewSource,它的工作原理。然後,當我點擊相反的複選框,而不是其他過濾器被添加到CollectionViewSource和這兩個過濾器工作,我的列表視圖變空白(當它不應該基於數據,這發生在任何一個檢查我的複選框的順序)

下面是相關代碼:(背景:與過濾 「訂單」 本應用程序處理的運輸軟件)

加載訂單:

public class Order 
{ 
    public int index { get; set; } 
    public string host { get; set; } 
    public Int64 orderNumber { get; set; } 
    public string batchStatus { get; set; } 
    public string sku { get; set; } 
    public int numItems { get; set; } 
    public string orderSource { get; set; } 
    public string sourceOrderNumber { get; set; } 
    public DateTime orderDate { get; set; } 
    public DateTime orderTime { get; set; } 
    public int customerID { get; set; } 
    public string shipMethod { get; set; } 
    public string billingState { get; set; } 
    public bool statusChanged { get; set; } 
    public int numSkus { get; set; } 
    public string marketName { get; set; } 
    public float weight { get; set; } 
} 

public class Orders : ObservableCollection<Order> 
{ 
    public Orders() 
    { 
     SqlDataReader reader1 = cmd.ExecuteReader(); 
     while (reader1.Read()) 
     { 
      Order order = new Order(); 

      order.host = (string)safeGetString(reader1, 0); 
      order.orderNumber = (Int64)reader1["OrderNumber"]; 
      order.batchStatus = (string)safeGetString(reader1, 2); 
      order.orderSource = (string)safeGetString(reader1, 3); 
      order.sourceOrderNumber = safeGetString(reader1, 4); 
      order.orderDate = (DateTime)reader1["OrderDate"]; 
      order.customerID = (int)reader1["CustomerID"]; 
      order.shipMethod = (string)safeGetString(reader1, 7); 
      order.billingState = (string)safeGetString(reader1, 8); 
      order.numItems = (int)reader1["NumItems"]; 
      order.numSkus = (int)reader1["NumSKUs"]; 
      order.marketName = (string)safeGetString(reader1, 11); 
      order.weight = (float)(double)reader1["ShippedWeight"]; 


      this.Add(order); 
     } 
     reader1.Close(); 
    } 

設置CollectionViewSource:

cvs = (CollectionViewSource)(this.Resources["cvs"]); 

複選框功能:

public void checkBox2_Checked(object sender, RoutedEventArgs e) 
    { 
     filterString = "TX"; 
     cvs.Filter += new FilterEventHandler(billingStateFilter); 
    } 
    public void checkBox1_Checked(object sender, RoutedEventArgs e) 
    { 
     filterString = "Standard"; 
     cvs.Filter += new FilterEventHandler(shippingMethodFilter); 
    } 

最後,過濾器(硬編碼使用filterString測試 「如何通過過濾器」):

private void shippingMethodFilter(object sender, FilterEventArgs e) 
    { 
     Order order = e.Item as Order; 
     if ((order.shipMethod != filterString)) 
     { 
      e.Accepted = false; 
     } 
    } 

    public void billingStateFilter(object sender, FilterEventArgs e) 
    { 
     Order order = e.Item as Order; 
     if ((order.billingState != filterString)) 
     { 
      e.Accepted = false; 
     } 
    } 

就像我說的,第一過濾器始終工作。第二個總是使屏幕變爲空白。有任何想法嗎?

+0

因此,您確定您的記錄既是TX又是Standard?在調試中處理程序被稱爲? – Paparazzi

回答

1

您正在爲兩個過濾器重新使用過濾器字符串,並且一旦您檢查每個框兩個過濾器都將被應用。所以,如果你:

  1. 檢查checkBox1,然後filterString將是「標準」和shippingMethodFilter會被迷上了。
  2. 檢查checkBox2,然後filterString將爲「TX」,並且billingStateFilter將被掛鉤。

沒有什麼是shippingMethodFilter解除鉤。所以它將繼續基於「TX」的filterString進行過濾。

您應該添加一個過濾器方法,檢查checkBox1/checkBox2是否被選中,然後可以選擇應用它的過濾邏輯。喜歡的東西:

private string shippingFilterString = "Shipping"; 
private string billingFilterString = "TX"; 

private void collFilter(object sender, FilterEventArgs e) 
{ 
    Order order = e.Item as Order; 
    if (checkBox1.IsChecked == true && (order.shipMethod != shippingFilterString)) 
     e.Accepted = false; 
    if (checkBox2.IsChecked == true && (order.billingState != billingFilterString)) 
     e.Accepted = false; 
} 
+0

啊,我明白了,有道理。雖然...... –

+0

因此,如果我有多個基於從數據庫檢索到的數據動態創建的複選框過濾器,那麼創建這些「過濾器字符串」的理想方法是什麼,以便多個過濾器可以應用時不會相互干擾? –

+0

@ user1667022 - 這真的取決於你的需求。你可以建立一個'Func '代表名單。或者只是有一個字符串列表以及它們與哪些屬性相關聯。很難說最好的方法是:-) – CodeNaked

0
for (i = 0; i < numberItemsFilterStrings.Length; i++) 
      { 
       switch (numberItemsFilterStrings[i]) 
       { 
        case "One Item": 
         if (order.numItems != 1) 
         { 
          e.Accepted = false; 
         } 
         break; 
        case "Between 2 - 5": 
         if ((order.numItems < 2) || (order.numItems > 5)) 
         { 
          e.Accepted = false; 
         } 
         break; 
        case "Between 6 - 25": 
         if ((order.numItems < 6) || (order.numItems > 24)) 
         { 
          e.Accepted = false; 
         } 
         break; 
        case "Greater Than 25": 
         if (order.numItems < 25) 
         { 
          e.Accepted = false; 
         } 
         break; 
       } 
      } 

所以這是我創建一個過濾器的代碼。它適用於第一個過濾器,因爲所有不匹配過濾器的訂單都不被接受。但是,當我檢查的第二過濾器框,然後沒有任何訂單的顯示出來,因爲從最初被接受真實的訂單,現在他們還沒有接受離開沒有訂單

+0

並且現在存儲不同的過濾器字符串在那個數組中numberItemsFilterStrings –

0

我已經發表了一篇博客上這樣的: https://hoomanvisualstudio.blogspot.com/b/post-preview?token=mpPyAk0BAAA.ygnewdzslszANX8AchX0hg.uW17QZR22-f_JUqjDTBcyA&postId=4200491240358821673&type=POST

有這麼多的方法。一個簡單的方法是將你的條件放到一個謂詞中。

MyViewModel myViewModel = new MyViewModel();

//將收集你的過濾器 var _itemSourceList = myViewModel.MyCollection;

變種濾波器=新謂詞(項目=>((型號)項).FirstName.ToString()。包含( 「約翰」)& &((型號)項).LastName.ToString()。包含(」 DOE「));

_itemSourceList.Filter = filter; myDataGrid.ItemsSource = myViewModel.MyCollection;