C#为什么这个循环这么慢?

时间:2009-06-07 23:49:53

标签: c# datagrid

我继承了一些将过滤器应用于数据网格的代码,当数据网格中有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

// .....         }

有什么想法吗? 谢谢大家

3 个答案:

答案 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));