2012-10-05 190 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;