2011-08-11 9 views
1

내 datagridview는 데이터 테이블에 바인딩됩니다. 데이터 테이블에 영향을주지 않고 DataGridview를 필터링하고 싶습니다. 바인딩 방법을 사용하는 것이 하나의 방법이지만 바인딩 소스는 필터에 열 이름을 사용합니다. 그러나 사용자가 필터링 할 텍스트 상자에 문자열을 입력 할 수있게하려고합니다. 그래서 datagridview에서 불필요한 행을 제거하는 함수 PassFilter를 참조하여 datagridview를 전달합니다. DataGridview에서 행 제거를 실행한다는 것을 알 수 있습니다. 그러나 문제는 양식에 datagridview가 표시 될 때 변경되지 않으며 데이터 테이블과 동일하다는 것입니다.vb.net에서 datagridview의 행을 제거 할 수 없습니다.

DataGridView1.DataSource = table 

PassFilter(DataGridView1, m_FilterQuick.strFilter.ToLower()) 
Private Sub PassFilter(ByRef datagridview As DataGridView, ByVal strFilter As String) 
    Dim i As Integer = 0 
    Dim j As Integer = 0 
    Dim containStr As Boolean = False 

    While i < datagridview.Rows.Count 
     j = 0 
     containStr = False 
     'If all cells in a row does not contain strFilter, delete this row from datagridview 
     While j < datagridview.Rows(i).Cells.Count 
      Dim c As DataGridViewCell = datagridview.Rows(i).Cells(j) 
      If Not c.Value Is DBNull.Value Or Nothing Then 
       If c.Value.ToString().ToLower().Contains(strFilter) Then 
        containStr = True 
        Exit While 
       End If 

      End If 
      j = j + 1 
     End While 
     If Not containStr Then 
      datagridview.Rows.RemoveAt(i) 
     End If 
     i = i + 1 
    End While 

End Sub 

답변

0

하는 읽기 전용 또는 편집을 위해 같은 데이터를 표시하고 있습니까 : 행이 DataGridView에에 제거되지 않습니다 이유는 다음과 같이

코드가 이해가 안 돼요?

사용자가 수정할 수 있도록 허용하려는 경우 표시하지 않으려는 행을 삭제하지 않고 숨길 수있는 방법을 찾을 수 있습니까?

당신이 읽기 전용, 당신은 필터링 한 후 데이터를 잡아 수 있고 .... 새로운 DataGridView에로 던져으로이를 표시하는 경우 (예, 추한,하지만 가능한 옵션)

오 기다려 ... 참조 대신 값으로 datagridview를 전달하면 제거시 변경 사항이 유지됩니다.

+0

한 가지 가능한 솔루션은 원치 않는 행이 보이지 않게하는 것입니다. 하지만 datagridview는 데이터 소스에 바인딩되어 있으므로주의해야합니다. 스레드 http://social.msdn.microsoft.com/Forums/en/Vsexpressvcs/thread/606c4ba0-754e-4789-8d7b-7fc428b76ba6 행을 볼 수 없게 만들 수 있습니다. Me.DataGridView.CurrentCell = 아무 것도 없음 Me.DataGridView.Rows (index) .Visible = False – Summer

+0

현재 datagridview가 디자이너를 통해 양식에 추가되었으므로 새 datagridview에 던져 넣을 수 없습니다. 또한 값으로 전달하면 분명히 작동하지 않습니다 – Summer

+0

visible 속성을 false로 설정하는 문제는 매우 느립니다 !!! – Summer

3

큰 문제는 해당 컬렉션을 반복하면서 DataGridViewRowCollection에서 항목을 제거한다는 것입니다. 이 작업을 수행하는 중에 '범위를 벗어난 인덱스'오류가 발생하지 않더라도 이전 행을 제거 할 때 이후 행의 인덱스 값이 변경되므로 잘못된 행을 제거하게됩니다.

행 루프에서 행을 제거하는 대신 행 인덱스를 List(Of Integers)에 추가하십시오.

당신이 당신의 DataGridView에, Reverse() 목록에 모든 행을 반복하고 RemoveAt() 방법을 통해 행을 제거하기 위해 List의 행 인덱스 값을 사용을 완료 한 후.

은 여기의 의미는 다음과 같습니다

Private Sub PassFilter(ByRef datagridview As DataGridView, ByVal strFilter As String) 
    Dim i As Integer = 0 
    Dim j As Integer = 0 
    Dim containStr As Boolean = False 
    ' Row indexes we'll remove later on. 
    Dim deleteIndexList As List(Of Integer) = New List(Of Integer) 

    While i < datagridview.Rows.Count 
     j = 0 
     containStr = False 
     'If all cells in a row does not contain strFilter, delete this row from datagridview 
     While j < datagridview.Rows(i).Cells.Count 
      Dim c As DataGridViewCell = datagridview.Rows(i).Cells(j) 
      ' Note: you'll want to enclose the tests for DBNull.Value and Nothing in parens like I show here. 
      If Not (c.Value Is DBNull.Value And c.Value Is Nothing) Then 
       If c.Value.ToString().ToLower().Contains(strFilter) Then 
        containStr = True 
        Exit While 
       End If 

      End If 
      j = j + 1 
     End While 
     If Not containStr Then 
      ' Don't remove rows here or your row indexes will get out of whack! 
      ' datagridview.Rows.RemoveAt(i) 
      deleteIndexList.Add(i) 
     End If 
     i = i + 1 
    End While 

    ' Remove rows by reversed row index order (highest removed first) to keep the indexes in whack. 
    deleteIndexList.Reverse() 
    For Each idx As Integer In deleteIndexList 
     datagridview.Rows.RemoveAt(idx) 
    Next 
End Sub 
+0

@Summer 당신이하고있는 일을 볼만큼 충분히 가까이서 Q를 읽지는 않았지만 나쁜 조언을 해주었습니다.하지만 제 대답을 수정하고 당신의 방법을 재 작성하여 제가 의미하는 바를 보여주었습니다 . –

+0

저는 이런 식으로해야 할 일이 항상 싫었습니다. 삭제를 위해 행을 표시하는 방법이 있었으면 좋겠다. 그런 다음 루프를 실행 한 후 실행하면 색인 순서/계산이 깨지지 않았다. 내 방식은 조금 더 간단하지만 같은 개념입니다. – Keith

관련 문제