我有一个 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() + "<> ";
}
}
但是,我不知道如何动态地提出这样的表达式的右手边。有什么想法我能做什么?我有点想我应该只继承这个 Checkbox 控件并添加 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 秒),所以我需要接下来解决这个问题......