2009-06-07 4 views
1

필터를 DataGrid에 적용하는 코드를 상속했지만 필터가 작동하지만 DataGrid에 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

가장 좋은 추측은 두 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와 두 개의 버튼이있는 간단한 양식을 만들었습니다. 첫 번째 버튼에이 데이터 테이블을 적용 클릭하고 두 번째에 그것을 필터 : 두 번째 버튼을 클릭하면

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

기본보기를 사용하지 않는 것이 좋습니다 ... 당신은 어딘가에 숨겨진 데이터가 필요할 수 있으며 그렇게하면 기본보기에 나타나지 않습니다. 테이블에 새 DataView를 만드는 것이 더 좋습니다. 그렇지 않으면, 좋은 대답, 나는 그것을 투표;) –

1

아마도 느린 이유는 Contains 메서드를 호출 할 때마다 찾고있는 것이 발견 될 때까지 filteredRows 목록의 모든 행을 반복해야한다는 것입니다. 즉, 루프를 통해 매번 500 번까지 반복적으로 루프 할 수 있습니다.

BFree는 문제를 해결하는 방법에 대한 정답을 가지고 있습니다. 그러나 테이블에 둘 이상의 것을 바인딩하는 경우 대신 BindingSource에 바인딩 할 수 있습니다. 바인딩 소스에는 설정할 수있는 필터 속성이 있습니다.

관련 문제