2009-06-07 19 views
1

フィルタはデータグリッドに適用されるコードを継承していますが、フィルタは機能しますが、データグリッドに500以上の行がある場合、フィルタは機能しますが(500以上でハングアップし、100行でうまく動作します)、フィルタは基本的に「お支払いいただいた皆を見せてください」または「X国の皆さんに見せてください」C#なぜこのループは遅いのですか?

フィルタに一致する行のリスト(filtered filtered below)は即座に作成されます。

 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

2つのDataRowインスタンスを比較する方法と関係があります。フィルタリングを自分で行うには理由がありません

HashSet<DataRow> filteredRows = new HashSet<DataRow>(table.Select(strSearchFilter)); 
+0

ハッシュセットは.net 3.5ですか?私は.net 2.0を使用しています。ありがとうございます –

+0

ああ、それは.NET 3.5のものです – AgileJon

12

List<DataRow> filteredRows = new List<DataRow>(table.Select(strSearchFilter)); 

を交換してみてください。 DataGridViewがDataTableにバインドされている場合(それはそうだと思われます)、DataTable.DefaultView.RowFilterプロパティを使用します。サンプルが来る...

私はDataGridViewと2つのボタンで簡単なフォームを作成しました。最初のボタンの上にはデータテーブルを適用]をクリックし、2つ目に、それはそれをフィルタリング:あなたは番目のボタンをクリックすると

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を参照してください。

+0

私はデフォルトのビューを使用してrecommand ...どこか他の隠しデータが必要な場合があり、それを行う場合、デフォルトの表示で表示されません。テーブルに新しいDataViewを作成する方が良いと思います。そうでなければ、良い答え、私はそれを投票する;) –

1

おそらく遅い理由は、Containsメソッドを呼び出すたびに、探しているものが見つかるまで、filteredRowsリストのすべての行をループする必要があるからです。これは、ループのたびに500回ループする可能性があることを意味します。

BFreeには、問題の解決方法に関する正しい答えがあります。ただし、テーブルに複数のものをバインドする場合は、代わりにBindingSourceにバインドすることができます。バインディングソースには、設定できるフィルタプロパティがあります。

関連する問題