2012-10-05 1 views
2

У меня есть ListView, который ограничен CollectionViewSource. Я следил за этой статьей (многие из них) за несколько фильтров: http://www.zagstudio.com/blog/456#.UG8r6E1lWLEНесколько фильтров WPF 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"]); 

Функция Checkbox: (Запрограммированный "что фильтровать" с помощью 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; 
     } 
    } 

Как я уже сказал, первый фильтр всегда работает. Второй всегда делает экран незаполненным. Есть идеи?

+0

Итак, у вас есть записи, которые являются как TX, так и стандартными? В отладке называются обработчики? – Paparazzi

ответ

1

Вы повторно используете строку фильтра для обоих фильтров, и после того, как вы проверите каждое поле , будут применяться фильтры. Так что если вы:

  1. Check checkBox1, тогда filterString будет «стандартным», а shippingMethodFilter будет подключен.
  2. Проверьте checkBox2, затем filterString будет «TX», а биллингStateFilter будет подключен.

Ни в коем случае не является отправкойMethodFilter незанятым. Поэтому он будет продолжать фильтровать на основе filterString «TX».

Возможно, вы должны добавить один метод фильтра, который проверяет, проверен ли 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

Ahhh Я вижу, имеет смысл. Никогда бы не подумал об этом, хотя ... –

+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 = новый MyViewModel();

// Коллекция, в которой будет выбран ваш фильтр var _itemSourceList = myViewModel.MyCollection;

вар фильтр = новый Предикат (пункт => ((Model) пункт) .FirstName.ToString(). Содержит ("John") & & ((модель) пункт) .LastName.ToString(). Содержит (» Doe "));

_itemSourceList.Filter = фильтр; myDataGrid.ItemsSource = myViewModel.MyCollection;

Смежные вопросы