动态设置数据表的行筛选器

本文关键字:筛选 设置 数据表 动态 | 更新日期: 2023-09-27 18:35:53

我有一个DataTable,在运行时构建了多达20K行,然后扔进了DevExpress GridControl。我添加了两个过滤选项,这两个选项最初是在运行查询时检查的......这意味着,如果要更改选项,则必须重新查询并重建此庞大的DataTable,然后删除不需要的行。显然,这是非常低效和耗时的。我决定尝试让它变得更好一点,不让它重建 DataTable,而只是过滤它。

最初,我想出了这个看起来很糟糕的代码块:

if (!cheBinObjFolders.Checked)
{
   dt.DefaultView.RowFilter = "File NOT LIKE '*bin*'";
   dt.DefaultView.RowFilter += " AND File NOT LIKE '*obj*'";
   isFiltered = true;
}
else
{
   if (!isFiltered)
   {
      dt.DefaultView.RowFilter = "File <> ''";
      isFiltered = true;
   }
   else
      dt.DefaultView.RowFilter += " AND File <> ''";
}
if (cheNormalFiles.Checked)
{
   if (!isFiltered)
      dt.DefaultView.RowFilter = "Status <> ''";
   else
      dt.DefaultView.RowFilter += " AND Status <> ''";
}
else
{
   if (!isFiltered)
      dt.DefaultView.RowFilter = "Status NOT LIKE '*Normal*'";
   else
      dt.DefaultView.RowFilter += " AND Status NOT LIKE '*Normal*'";
}

所以我想改进它,让它更干净、更容易,如果添加更多的过滤选项。因此,我将复选框上的 Tag 属性设置为列名称("文件"或"状态"),复选框将过滤并编写以下内容:

//Empty quotes should be the actual right-hand side of the expression
foreach (Control c in this.Controls)
{
   if (c is CheckEdit)
   {
      if (((CheckEdit)c).Checked && isFiltered)
         dt.DefaultView.RowFilter += c.Tag.ToString() + "";
      else if (((CheckEdit)c).Checked)
      {
         dt.DefaultView.RowFilter = c.Tag.ToString() + "";
         isFiltered = true;
      }
      else
         dt.DefaultView.RowFilter = c.Tag.ToString() + "<> ";
   }
}

但是,我不知道如何动态地想出这样的表达式的右侧。知道我能做什么吗?我有点想我应该只子类化这个复选框控件并添加 2 个字符串属性;"字段"和"过滤器"然后使用它们来构建我的过滤器。有没有更好的方法?

编辑:好的,我想出了你的建议/建议:

    private string BuildTableFilter()
    {
        foreach (Control control in this.Controls)
        {
            if (control is CheckEdit && control.Tag != null)
            {
                var c = (CheckEdit)control;
                if (c.Checked)
                {
                    if (!filters.Contains(c.Tag.ToString()))
                        filters.Add(c.Tag.ToString());
                }
                else
                    filters.Remove(c.Tag.ToString());
            }
        }
        return String.Join(" AND ", filters.ToArray());
    }

因此,我将来需要做的就是将适当的过滤器表达式添加到标签中。不幸的是,由于行太多,它仍然会短暂锁定 UI(也许是 5 秒),所以我接下来需要解决这个问题......

动态设置数据表的行筛选器

您可能希望使用语句列表生成查询(在本例中,Tag 将是该控件的筛选器语句);

 var filterTerms = new List<string>();
 foreach (Control c in this.Controls)
 {
     if (c is CheckEdit)
     {
        if (((CheckEdit)c).Checked)
        {
             filterTerms.Add(c.Tag.ToString());
        }
     }
 }
 dt.DefaultView.RowFilter = string.Join(" AND ", filterTerms);