有没有办法过滤和限制 DataGridView 中的行?
Is there a way to filter and limit rows in a DataGridView?
我正在编写一个销售程序,为此我需要一个浏览器 window,用户可以在其中浏览他所有待售的产品。这可能意味着数以千计的产品,因此过滤是唯一的出路。我发现最快的过滤方法是用产品填充 DataTable(而不是直接填充 DataGridView,这是我的第一个解决方案)并使用其过滤功能。
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
}
这完成了仅可视化销售人员(从现在开始:用户)正在寻找什么的工作,并且它完美地工作了大约 300 行(产品)。
将此增加到 10000 种产品(这不仅仅是为了测试商店的当前数据库)并且加载时间从 1 秒呈指数增长到 40,这在销售环境中是不可接受的。
产品在后台的 MySQL 数据库中。查询并将其保存到 DataTable 花费的时间不到一秒钟,这对于 10000 种产品来说是可以接受的,当我尝试将其可视化时,问题就来了。一个简单的:
datagridview1.DataSource = browseDataTable;
大约需要 4 秒,这是可以接受的,但是对于这个应用程序,我需要为我的 6 列添加样式 + header(所有列都有不同的字体,有些换行,有些不换行,等),这将加载时间增加到大约 40 秒,但如果没有样式,在光线充足的房间中使用质量较低的触摸显示器,用户将无法看到行。
限制它是要走的路,我没有找到更好的解决方案然后使用这样的东西
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges);
datagridview1.DataSource = visibleDataTable;
这使得可视化时间再次缩短了 1 秒。
我的问题是当我尝试将限制与过滤后的产品一起使用时(仅可视化过滤后的前 100 行)。 尝试组合哪个 DataTable 应该是DataGridView 的数据源是这样的:
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges); //done once somewhere
private void nameTB_TextChanged(object sender, EventArgs e)
{
if(nameTB.Text == "")
datagridview1.DataSource = visibleDataTable;
else
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
datagridview1.DataSource = browseDataTable;
}
}
没用,因为通常还有太多产品最多 3 个字母,每个字母后有 5 秒的延迟,3-4 个字母后,它是瞬时的。
理想的解决方案是这样的:
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges);
}
但这也不起作用,因为 'Take(100)' 总是从 DataTable 中取出前 100 个,无论是否过滤。
(限制查询本身也行不通,因为那样的话每个字母都会有一个查询,而联网服务器会增加网络拥塞并且会很慢,尤其是当用户开始快速写入时)
原来答案比我想的要简单
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
visibleDataTable = browseDataTable.DefaultView.ToTable().AsEnumerable().Take(100).CopyToDataTable();
datagridview1.DataSource = visibleDataTable;
}
这会过滤到我想要的字母,并将行数限制为 100,这使得整个过程瞬间完成。
我正在编写一个销售程序,为此我需要一个浏览器 window,用户可以在其中浏览他所有待售的产品。这可能意味着数以千计的产品,因此过滤是唯一的出路。我发现最快的过滤方法是用产品填充 DataTable(而不是直接填充 DataGridView,这是我的第一个解决方案)并使用其过滤功能。
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
}
这完成了仅可视化销售人员(从现在开始:用户)正在寻找什么的工作,并且它完美地工作了大约 300 行(产品)。 将此增加到 10000 种产品(这不仅仅是为了测试商店的当前数据库)并且加载时间从 1 秒呈指数增长到 40,这在销售环境中是不可接受的。
产品在后台的 MySQL 数据库中。查询并将其保存到 DataTable 花费的时间不到一秒钟,这对于 10000 种产品来说是可以接受的,当我尝试将其可视化时,问题就来了。一个简单的:
datagridview1.DataSource = browseDataTable;
大约需要 4 秒,这是可以接受的,但是对于这个应用程序,我需要为我的 6 列添加样式 + header(所有列都有不同的字体,有些换行,有些不换行,等),这将加载时间增加到大约 40 秒,但如果没有样式,在光线充足的房间中使用质量较低的触摸显示器,用户将无法看到行。 限制它是要走的路,我没有找到更好的解决方案然后使用这样的东西
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges);
datagridview1.DataSource = visibleDataTable;
这使得可视化时间再次缩短了 1 秒。
我的问题是当我尝试将限制与过滤后的产品一起使用时(仅可视化过滤后的前 100 行)。 尝试组合哪个 DataTable 应该是DataGridView 的数据源是这样的:
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges); //done once somewhere
private void nameTB_TextChanged(object sender, EventArgs e)
{
if(nameTB.Text == "")
datagridview1.DataSource = visibleDataTable;
else
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
datagridview1.DataSource = browseDataTable;
}
}
没用,因为通常还有太多产品最多 3 个字母,每个字母后有 5 秒的延迟,3-4 个字母后,它是瞬时的。
理想的解决方案是这样的:
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges);
}
但这也不起作用,因为 'Take(100)' 总是从 DataTable 中取出前 100 个,无论是否过滤。
(限制查询本身也行不通,因为那样的话每个字母都会有一个查询,而联网服务器会增加网络拥塞并且会很慢,尤其是当用户开始快速写入时)
原来答案比我想的要简单
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
visibleDataTable = browseDataTable.DefaultView.ToTable().AsEnumerable().Take(100).CopyToDataTable();
datagridview1.DataSource = visibleDataTable;
}
这会过滤到我想要的字母,并将行数限制为 100,这使得整个过程瞬间完成。