ICollectionView множественный фильтр - PullRequest
1 голос
/ 19 июня 2020

Итак, у меня есть текстовое поле Fitler, в котором я хочу искать различные типы документов в сетке, код, в котором у меня есть столбцы другого типа, такие как: Date, DocId, ClientId. Для поиска я пишу в текстовом поле фильтра что-то вроде этого DocId:2002, и он просто работает нормально, но когда я пытаюсь выполнить многократный поиск, например DocId:2002 ClientId:201, он не выполняет поиск из-за возврата, он просто выполняет бесконечное l oop .

private void TextBoxFilter_TextChanged(object sender, TextChangedEventArgs e)
    {
      foreach (Match m in Regex.Matches((sender as TextBox).Text, pattern, options))
      {
        if (m.Value != "")
        {
          Func<String, String> untilSlash = (s) => { return filters[re.Match(s).Groups[1].ToString()] = re.Match(s).Groups[2].ToString(); };
          untilSlash(m.Value);
        }
      }
      ICollectionView cv = CollectionViewSource.GetDefaultView(this.DataGridDocList.ItemsSource);
      if (filters.Count == 0)
      {
        cv.Filter = null;
      }
      else
      {
        cv.Filter = o =>
        {
          for (int i = 0; i < filters.Count; i++)
          {

            if (filters.ElementAt(i).Key == "Date")
            {
              if (DateVerify.Match(filters.ElementAt(i).Value).Success)
              {
                return (o as Document).DateCreated < Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()) && (o as Document).DateCreated > Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[2].ToString());
              }
              else
              {
                var dateString = (o as Document).DateCreated.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
                return dateString.Contains(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString());
              }
            }
            if (filters.ElementAt(i).Key == "DocId")
            {
              return (o as Document).DocumentId.ToString().Contains(filters.ElementAt(i).Value);
            }
            if (filters.ElementAt(i).Key == "ClientId")
            {
              return (o as Document).ClientId.ToUpper().Contains(filters.ElementAt(i).Value.ToUpper());
            }
          }
          return false;
        };
        filters.Clear();
      }
    }

Итак, мой вопрос в том, как я могу выполнить большой поиск со всеми фильтрами одновременно? Вручную я могу добавить их 1 к 1, и это будет что-то вроде search1 && search2 && search3, но это займет слишком много времени и, вероятно, это не лучшее решение

1 Ответ

1 голос
/ 22 июня 2020

Есть много способов построить предикат. Однако я предлагаю не усложнять задачу и просто создать один метод, который возвращает true или false . Рекомендуется возвращать только один раз в методе .

Код ниже, если для иллюстрации (поскольку я не могу его проверить):

ICollectionView cv = CollectionViewSource.GetDefaultView(this.DataGridDocList.ItemsSource);

if (filters.Any())
{
    cv.Filter = new Predicate<object>(PredicateFilter);
}
else
{
    cv.Filter = null;
}    

Затем метод Predicate для фильтрации результатов:

public bool PredicateFilter(object docObj)
{
    Document doc = docObj as Document;

    var response = new List<bool>();    

    for (int i = 0; i < filters.Count; i++)
    {
        if (filters.ElementAt(i).Key == "Date")
        {
            if (DateVerify.Match(filters.ElementAt(i).Value).Success)
            {
                response.Add(doc.DateCreated < Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()) && doc.DateCreated > Convert.ToDateTime(DateVerify.Match(filters.ElementAt(i).Value).Groups[2].ToString()));
            }
            else
            {
                var dateString = doc.DateCreated.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
                response.Add(dateString.Contains(DateVerify.Match(filters.ElementAt(i).Value).Groups[1].ToString()));
            }
        }
        else if (filters.ElementAt(i).Key == "DocId")
        {
            response.Add(doc.DocumentId.ToString().Contains(filters.ElementAt(i).Value));
        }
        else if (filters.ElementAt(i).Key == "ClientId")
        {
            response.Add(doc.ClientId.ToUpper().Contains(filters.ElementAt(i).Value.ToUpper()));
        }
    }
            
    return response.All(m => m); // if all filters came back with true, return 1 response of true else false.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...