ICollectionView多个过滤器

诅咒

所以我有一个fitler TextBox,我想在网格中搜索具有不同类型列的代码,例如Date,DocId,ClientId。对于搜索,我在过滤器文本框上写了类似的内容,DocId:2002它工作正常,但是例如当我尝试进行多次搜索时,DocId:2002 ClientId:201由于返回而没有搜索,它只会执行无限循环。

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

所以我的问题是如何一次对所有过滤器进行一次大搜索?手动地,我可以将它们一对一地添加,这将类似于search1 && search2 && search3,但是这将花费太多时间,并且可能不是最佳解决方案

格雷格

建立谓词的方法有很多。但是我的建议是保持简单,只创建一个返回truefalse的方法优良作法是只在方法中返回一次

下面的代码是否出于说明目的(因为我无法对其进行测试):

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

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

然后用谓词方法过滤结果:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章