WPF多个过滤器CollectionViewSource,添加的第一个过滤器正常工作,添加的第二个过滤器不正常 [英] WPF multiple filters CollectionViewSource, first filter added works correctly, second filter added does not

查看:143
本文介绍了WPF多个过滤器CollectionViewSource,添加的第一个过滤器正常工作,添加的第二个过滤器不正常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个绑定到CollectionViewSource的ListView.我遵循了这篇文章(被许多人引用)进行多重过滤: http://www.zagstudio. com/blog/456#.UG8r6E1lWLE

我设置了两个用于测试的复选框,它们除了添加过滤器外什么也不做.每当我单击任一按钮时,该过滤器就会添加到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"]);

复选框功能:(使用filterString进行硬编码的过滤条件")

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);
    }

最后,过滤器:

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;
        }
    }

就像我说的那样,第一个过滤器始终有效.第二个总是使屏幕空白.有什么想法吗?

解决方案

您正在为两个过滤器重新使用过滤器字符串,并且一旦选中每个框,将同时应用两个过滤器.因此,如果您:

  1. 选中checkBox1,然后filterString将为"Standard",并将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;
}

I have a ListView that is bounded to a CollectionViewSource. I followed this article (refered to by many) for multiple filtering: http://www.zagstudio.com/blog/456#.UG8r6E1lWLE

I have two checkboxes set up for testing that do nothing but add a filter. Whenever I click on either one first, the filter is added to the CollectionViewSource and it works. Then when I click on the opposite checkbox, instead of the other filter being added to the CollectionViewSource and both filters working, my listview goes blank (when it shouldnt based on the data, and this happens in either order of checking my checkboxes)

Here is the relevant code: (Background: this application deals with filtering "Orders" for shipping software)

Loading Orders:

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();
    }

Setting up CollectionViewSource:

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

Checkbox Functions: (Hardcoded "what to filter by" using filterString for testing)

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);
    }

And lastly, the filters:

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;
        }
    }

Like I said, the first filter always works. The second always makes the screen blank. Any ideas?

解决方案

You are re-using the filter string for both filters and once you check each box both filters will be applied. So if you:

  1. Check checkBox1, then filterString will be "Standard" and shippingMethodFilter will be hooked up.
  2. Check checkBox2, then filterString will be "TX" and billingStateFilter will be hooked up.

At no point is shippingMethodFilter unhooked. So it will continue to filter based on a filterString of "TX".

You should probably add one filter method that checks to see if checkBox1/checkBox2 is checked and then optionally apply it's filtering logic. Something like:

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;
}

这篇关于WPF多个过滤器CollectionViewSource,添加的第一个过滤器正常工作,添加的第二个过滤器不正常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆