我继承了一些将过滤器应用于数据网格的代码,当数据网格中有500多行(它挂起超过500,工作正常,有100行)时,过滤器适用但速度非常慢,过滤器基本上说“告诉我所有付钱的人”或“向我展示X国的每个人”等。
立即创建与过滤器匹配的行列表(下面的filteredRows)。
if (comboBoxFilterCondition.Text == "Contains")
{
strSearchFilter += string.IsNullOrEmpty(txtFilterValue.Text) ? " IS NULL" : " LIKE '%" + txtFilterValue.Text + "%'";
}
FilterRows(strSearchFilter);
// ...
private void FilterRows(string strSearchFilter)
{
DataTable table = dataGridView1.DataSource as DataTable;
if (table != null)
{
List<DataRow> filteredRows = new List<DataRow>(table.Select(strSearchFilter)); //<----Very quick to here
CurrencyManager cm = (CurrencyManager)BindingContext[dataGridView1.DataSource];
cm.SuspendBinding();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.Visible = filteredRows.Contains(((DataRowView)row.DataBoundItem).Row); //<---Stuck here
}
cm.ResumeBinding(); //<----------Doesn't arrive here
// ..... }
有什么想法吗? 谢谢大家
答案 0 :(得分:12)
没有理由自己进行过滤。如果datagridview绑定到DataTable(似乎它是),只需使用DataTable.DefaultView.RowFilter属性。来样......
好的,我创建了一个带有DataGridView和两个按钮的简单表单。在第一个按钮上单击它会应用一个数据表,在第二个按钮上它会过滤它:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Age", typeof(int));
table.Rows.Add("John", 25);
table.Rows.Add("Jack", 34);
table.Rows.Add("Mike", 17);
table.Rows.Add("Mark", 54);
table.Rows.Add("Frank", 37);
this.dataGridView1.DataSource = table;
}
private void button2_Click(object sender, EventArgs e)
{
var table = this.dataGridView1.DataSource as DataTable;
table.DefaultView.RowFilter = "Age > 30";
}
单击第二个按钮时,网格将自动过滤。这应该比自己手动操作更快。看看我之前向您展示的链接,以及这个链接:http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx,了解有关构建过滤器表达式的更多信息。
答案 1 :(得分:1)
它可能很慢的原因是每次调用Contains方法时,它必须遍历filteredRows列表中的所有行,直到找到您要查找的那一行。这意味着每次循环可能会循环最多500次。
BFree对如何解决问题有正确的答案。但是我会补充说,如果你将多个东西绑定到表,你可以绑定到BindingSource。绑定源具有可以设置的过滤器属性。
答案 2 :(得分:0)
我最好的猜测是,它与如何比较两个DataRow实例有关。尝试替换
List<DataRow> filteredRows = new List<DataRow>(table.Select(strSearchFilter));
与
HashSet<DataRow> filteredRows = new HashSet<DataRow>(table.Select(strSearchFilter));