다음을 통해 공유


데이터 탐색(Windows Forms .NET)

데이터 원본의 레코드를 탐색하는 가장 쉬운 방법은 BindingSource 구성 요소를 데이터 원본에 바인딩한 다음, 컨트롤을 BindingSource에 바인딩하는 것입니다. 그런 다음, BindingSource에서 MoveNext, MoveLast, MovePreviousMoveFirst 등의 기본 제공 탐색 메서드를 사용할 수 있습니다. 이러한 메서드를 사용하면 BindingSourcePositionCurrent 속성을 적절하게 조정할 수 있습니다. 레코드를 찾고 Position 속성을 설정하여 해당 레코드를 현재 레코드로 설정할 수도 있습니다.

데이터 원본에서 레코드 위치를 증분하려면

바인딩된 데이터에 대한 BindingSourcePosition 속성을 필요한 레코드 위치로 이동하려는 레코드 위치로 설정합니다. 다음 예제에서는 BindingSourceMoveNext 메서드를 사용하여 nextButton을 선택할 때 Position 속성을 증분하는 방법을 보여 줍니다. BindingSource는 데이터 세트 NorthwindCustomers 테이블과 연결됩니다.

private void nextButton_Click(object sender, System.EventArgs e)
{
    this.customersBindingSource.MoveNext();
}
Private Sub nextButton_Click(ByVal sender As Object,
    ByVal e As System.EventArgs) Handles nextButton.Click
    Me.customersBindingSource.MoveNext()
End Sub

참고

Windows Forms는 목록 경계를 벗어난 값으로 위치를 설정하지 않으므로 Position 속성을 첫 번째 또는 마지막 레코드를 벗어나는 값으로 설정해도 오류가 발생하지 않습니다. 첫 번째 또는 마지막 레코드를 벗어났는지 여부를 알아야 하는 경우 데이터 요소 수를 초과할지 여부를 테스트하는 논리를 포함합니다.

첫 번째 레코드 또는 마지막 레코드를 초과했는지 검사하려면

PositionChanged 이벤트에 대한 이벤트 처리기를 만듭니다. 처리기에서 제안된 위치 값이 실제 데이터 요소 수를 초과했는지 여부를 테스트할 수 있습니다.

다음 예제에서는 마지막 데이터 요소에 도달했는지 여부를 테스트하는 방법을 보여줍니다. 이 예제에서 마지막 요소에 있다면 양식의 다음 단추를 사용할 수 없습니다.

void customersBindingSource_PositionChanged(object sender, EventArgs e)
{
    if (customersBindingSource.Position == customersBindingSource.Count - 1)
        nextButton.Enabled = false;
    else
        nextButton.Enabled = true;
}
Sub customersBindingSource_PositionChanged(ByVal sender As Object,
    ByVal e As EventArgs)

    If customersBindingSource.Position =
        customersBindingSource.Count - 1 Then
        nextButton.Enabled = False
    Else
        nextButton.Enabled = True
    End If
End Sub

참고

코드에서 탐색 중인 목록을 변경하는 경우 다음 단추를 다시 사용하도록 설정해야 사용자가 새 목록의 전체 길이를 찾아볼 수 있습니다. 또한 작업 중인 특정 BindingSource에 대한 위 PositionChanged 이벤트는 해당 이벤트 처리 메서드와 연결해야 합니다.

레코드를 찾고 현재 항목으로 설정하려면

현재 항목으로 설정하려는 레코드를 찾습니다. 데이터 원본이 IBindingList을(를) 구현하는 경우 예제와 같이 BindingSourceFind 메서드를 사용합니다. IBindingList를 구현하는 데이터 원본의 몇 가지 예는 BindingList<T>DataView입니다.

void findButton_Click(object sender, EventArgs e)
{
    int foundIndex = customersBindingSource.Find("CustomerID", "ANTON");
    customersBindingSource.Position = foundIndex;
}
Sub findButton_Click(ByVal sender As Object, ByVal e As EventArgs) _
    Handles findButton.Click
    Dim foundIndex As Integer = customersBindingSource.Find("CustomerID",
        "ANTON")
    customersBindingSource.Position = foundIndex
End Sub

자식 테이블에서 선택된 행이 올바른 위치에 유지되도록 설정하려면

Windows Forms에서 데이터 바인딩을 사용할 때 부모/자식 또는 마스터/세부 정보 보기에 데이터를 표시하게 됩니다. 동일한 소스의 데이터가 두 컨트롤에 표시되는 데이터 바인딩 시나리오를 가리킵니다. 한 컨트롤에서 선택 항목을 변경하면 두 번째 컨트롤에 표시되는 데이터가 변경됩니다. 예를 들어 첫 번째 컨트롤에는 고객 목록이 포함되고 두 번째 컨트롤에는 첫 번째 컨트롤에서 선택한 고객과 관련된 주문 목록이 포함될 수 있습니다.

부모/자식 보기에 데이터를 표시하는 경우 자식 테이블에서 현재 선택된 행이 테이블의 첫 번째 행으로 다시 설정되지 않도록 추가 단계를 수행해야 할 수도 있습니다. 이 작업을 수행하려면 자식 테이블 위치를 캐시하고 부모 테이블이 변경된 후 다시 설정해야 합니다. 일반적으로 자식 테이블 다시 설정은 부모 테이블의 행에 있는 필드가 처음 변경될 때 발생합니다.

현재 자식 테이블 위치를 캐시하려면

  1. 정수 변수를 선언하여 자식 테이블 목록 위치를 저장하고, 부울 변수를 선언하여 자식 테이블 위치를 캐시할지 여부를 저장합니다.

    private int cachedPosition = -1;
    private bool cacheChildPosition = true;
    
    Private cachedPosition As Integer = -1
    Private cacheChildPosition As Boolean = True
    
  2. 바인딩의 CurrencyManager에 대한 ListChanged 이벤트를 처리하고 ResetListChangedType을 확인합니다.

  3. CurrencyManager의 현재 위치를 확인합니다. 목록의 첫 번째 항목(일반적으로 0)보다 크면 변수에 저장합니다.

    void relatedCM_ListChanged(object sender, ListChangedEventArgs e)
    {
        // Check to see if this is a caching situation.
        if (cacheChildPosition && cachePositionCheckBox.Checked)
        {
            // If so, check to see if it is a reset situation, and the current
            // position is greater than zero.
            CurrencyManager relatedCM = sender as CurrencyManager;
            if (e.ListChangedType == ListChangedType.Reset && relatedCM.Position > 0)
    
                // If so, cache the position of the child table.
                cachedPosition = relatedCM.Position;
        }
    }
    
    Private Sub relatedCM_ListChanged(ByVal sender As Object,
        ByVal e As ListChangedEventArgs)
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            ' If so, check to see if it is a reset situation, and the current
            ' position is greater than zero.
            Dim relatedCM As CurrencyManager = sender
            If e.ListChangedType = ListChangedType.Reset _
                AndAlso relatedCM.Position > 0 Then
    
                ' If so, cache the position of the child table.
                cachedPosition = relatedCM.Position
            End If
        End If
    
    End Sub
    
  4. 부모 통화 관리자에 대한 부모 목록의 CurrentChanged 이벤트를 처리합니다. 처리기에서 캐싱 시나리오가 아님을 나타내는 부울 값을 설정합니다. CurrentChanged가 발생하는 경우 부모에 대한 변경 내용은 항목 값 변경이 아니라 목록 위치 변경입니다.

    void bindingSource1_CurrentChanged(object sender, EventArgs e)
    {
        // If the CurrentChanged event occurs, this is not a caching
        // situation.
        cacheChildPosition = false;
    }
    
    ' Handle the current changed event. This event occurs when
    ' the current item is changed, but not when a field of the current
    ' item is changed.
    Private Sub bindingSource1_CurrentChanged(ByVal sender As Object,
        ByVal e As EventArgs) Handles bindingSource1.CurrentChanged
        ' If the CurrentChanged event occurs, this is not a caching 
        ' situation.
        cacheChildPosition = False
    
    End Sub
    

자식 테이블 위치를 다시 설정하려면

  1. 자식 테이블 바인딩의 CurrencyManager에 대한 PositionChanged 이벤트를 처리합니다.

  2. 자식 테이블 위치를 이전 절차에서 저장된 캐시된 위치로 다시 설정합니다.

    void relatedCM_PositionChanged(object sender, EventArgs e)
    {
        // Check to see if this is a caching situation.
        if (cacheChildPosition && cachePositionCheckBox.Checked)
        {
            CurrencyManager relatedCM = sender as CurrencyManager;
    
            // If so, check to see if the current position is
            // not equal to the cached position and the cached
            // position is not out of bounds.
            if (relatedCM.Position != cachedPosition && cachedPosition
                > 0 && cachedPosition < relatedCM.Count)
            {
                relatedCM.Position = cachedPosition;
                cachedPosition = -1;
            }
        }
    }
    
    Private Sub relatedCM_PositionChanged(ByVal sender As Object, ByVal e As EventArgs)
        ' Check to see if this is a caching situation.
        If cacheChildPosition AndAlso cachePositionCheckBox.Checked Then
            Dim relatedCM As CurrencyManager = sender
    
            ' If so, check to see if the current position is 
            ' not equal to the cached position and the cached 
            ' position is not out of bounds.
            If relatedCM.Position <> cachedPosition AndAlso
                cachedPosition > 0 AndAlso cachedPosition <
                relatedCM.Count Then
                relatedCM.Position = cachedPosition
                cachedPosition = -1
            End If
        End If
    End Sub
    

코드 예제를 테스트하려면 다음 단계를 수행합니다.

  1. 예제를 실행합니다.

  2. 캐시 및 다시 설정 위치 확인란이 선택되었는지 확인합니다.

  3. 부모 필드 지우기 단추를 선택하여 부모 테이블의 필드를 변경합니다. 자식 테이블에서 선택한 행은 변경되지 않습니다.

  4. 예제를 닫고 다시 실행합니다. 다시 설정 동작이 부모 행을 처음 변경할 때만 발생하기 때문에 이 작업을 다시 실행해야 합니다.

  5. 캐시 및 다시 설정 위치 확인란을 선택 취소합니다.

  6. 부모 필드 지우기 단추를 클릭합니다. 자식 테이블에서 선택한 행이 첫 번째 행으로 변경됩니다.

참고 항목