다음을 통해 공유


연습: 하이브리드 애플리케이션에서 데이터에 바인딩

컨트롤에 데이터 원본 바인딩은 Windows Forms를 사용하는지 WPF를 사용하는지에 관계없이 기본 데이터에 대한 액세스 권한을 사용자에게 제공하는 데 필요합니다. 이 연습에서는 Windows Forms 및 WPF 컨트롤을 모두 포함하는 하이브리드 애플리케이션에서 데이터 바인딩을 사용하는 방법을 보여 줍니다.

이 연습에서 설명하는 작업은 다음과 같습니다.

  • 프로젝트 만들기.

  • 데이터 템플릿 정의

  • 폼 레이아웃 지정

  • 데이터 바인딩 지정

  • 상호 운용성을 사용하여 데이터 표시

  • 프로젝트에 데이터 소스 추가

  • 데이터 소스에 바인딩

이 연습에 설명된 작업의 전체 코드 목록은 하이브리드 애플리케이션의 데이터 바인딩 샘플을 참조하세요.

작업을 완료하면 혼합 애플리케이션의 데이터 바인딩 기능을 이해하게 됩니다.

필수 구성 요소

이 연습을 완료하려면 다음과 같은 구성 요소가 필요합니다.

  • Visual Studio.

  • Microsoft SQL Server에서 실행되는 Northwind 샘플 데이터베이스에 대한 액세스 권한.

프로젝트 만들기

프로젝트를 만들고 설정하려면

  1. WPFWithWFAndDatabinding라는 WPF 애플리케이션 프로젝트를 만듭니다.

  2. 솔루션 탐색기에서 다음 어셈블리에 대한 참조를 추가합니다.

    • WindowsFormsIntegration

    • System.Windows.Forms

  3. WPF Designer에서 MainWindow.xaml을 엽니다.

  4. Window 요소에서 다음 Windows Forms 네임스페이스 매핑을 추가합니다.

    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    
  5. Grid 속성을 할당하여 기본 mainGrid 요소의 이름을 Name로 지정합니다.

    <Grid x:Name="mainGrid">
    

데이터 템플릿 정의

고객의 마스터 목록은 ListBox 컨트롤에 표시됩니다. 다음 코드 예제는 DataTemplate 컨트롤의 시각적 트리를 제어하는 ListItemsTemplate이라는 ListBox 개체를 정의합니다. 이 DataTemplateListBox 컨트롤의 ItemTemplate 속성에 할당됩니다.

데이터 템플릿을 정의하려면

  • 다음 XAML을 Grid 요소 선언에 복사합니다.

    <Grid.Resources>
        <DataTemplate x:Key="ListItemsTemplate">
            <TextBlock Text="{Binding Path=ContactName}"/>
        </DataTemplate>
    </Grid.Resources>
    

폼 레이아웃 지정

폼의 레이아웃은 세 개의 행과 세 개의 열이 있는 그리드로 정의됩니다. Label 컨트롤은 Customers 테이블에서 각 열을 식별하기 위해 제공됩니다.

그리드 레이아웃을 설정하려면

  • 다음 XAML을 Grid 요소 선언에 복사합니다.

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    

레이블 컨트롤을 설정하려면

  • 다음 XAML을 Grid 요소 선언에 복사합니다.

    <StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="1">
        <Label Margin="20,38,5,2">First Name:</Label>
        <Label Margin="20,0,5,2">Company Name:</Label>
        <Label Margin="20,0,5,2">Phone:</Label>
        <Label Margin="20,0,5,2">Address:</Label>
        <Label Margin="20,0,5,2">City:</Label>
        <Label Margin="20,0,5,2">Region:</Label>
        <Label Margin="20,0,5,2">Postal Code:</Label>
    </StackPanel>
    

데이터 바인딩 지정

고객의 마스터 목록은 ListBox 컨트롤에 표시됩니다. 연결된 ListItemsTemplateTextBlock 컨트롤을 데이터베이스의 ContactName 필드에 바인딩합니다.

각 고객 레코드의 세부 정보가 여러 TextBox 컨트롤에 표시됩니다.

데이터 바인딩을 지정하려면

  • 다음 XAML을 Grid 요소 선언에 복사합니다.

    Binding 클래스는 TextBox 컨트롤을 데이터베이스의 적절한 필드에 바인딩합니다.

    <StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="0">
        <Label Margin="20,5,5,0">List of Customers:</Label>
        <ListBox x:Name="listBox1" Height="200" Width="200" HorizontalAlignment="Left" 
           ItemTemplate="{StaticResource ListItemsTemplate}" IsSynchronizedWithCurrentItem="True" Margin="20,5,5,5"/>
    </StackPanel>
    
    <StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="2">
        <TextBox Margin="5,38,5,2" Width="200" Text="{Binding Path=ContactName}"/>
        <TextBox Margin="5,0,5,2" Width="200" Text="{Binding Path=CompanyName}"/>
        <TextBox Margin="5,0,5,2" Width="200" Text="{Binding Path=Phone}"/>
        <TextBox Margin="5,0,5,2" Width="200" Text="{Binding Path=Address}"/>
        <TextBox Margin="5,0,5,2" Width="200" Text="{Binding Path=City}"/>
        <TextBox Margin="5,0,5,2" Width="30" HorizontalAlignment="Left" Text="{Binding Path=Region}"/>
        <TextBox Margin="5,0,5,2" Width="50" HorizontalAlignment="Left" Text="{Binding Path=PostalCode}"/>
    </StackPanel>
    

상호 운용성을 사용하여 데이터 표시

선택한 고객에 해당하는 주문은 System.Windows.Forms.DataGridView이라는 dataGridView1 컨트롤에 표시됩니다. dataGridView1 컨트롤은 코드 숨김 파일의 데이터 원본에 바인딩됩니다. WindowsFormsHost 컨트롤은 이 Windows Forms 컨트롤의 부모입니다.

DataGridView 컨트롤에 데이터를 표시하려면

  • 다음 XAML을 Grid 요소 선언에 복사합니다.

    <WindowsFormsHost Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Margin="20,5,5,5" Height="300">
        <wf:DataGridView x:Name="dataGridView1"/>
    </WindowsFormsHost>
    

프로젝트에 데이터 소스 추가

Visual Studio에서는 프로젝트에 데이터 원본을 쉽게 추가할 수 있습니다. 이 절차에서는 강력한 형식의 데이터 집합을 프로젝트에 추가합니다. 선택한 각 테이블에 대한 테이블 어댑터 같은 여러 가지 다른 지원 클래스도 추가됩니다.

데이터 소스를 추가하려면

  1. 데이터 메뉴에서 새 데이터 원본 추가를 선택합니다.

  2. 데이터 소스 구성 마법사에서 데이터 세트를 사용하여 Northwind 데이터베이스에 대한 연결을 만듭니다. 자세한 내용은 How to: Connect to Data in a Database을 참조하십시오.

  3. 데이터 소스 구성 마법사에서 메시지가 표시되면 연결 문자열을 NorthwindConnectionString으로 저장합니다.

    Important

    암호와 같은 중요한 정보를 연결 문자열 내에 저장하면 애플리케이션 보안 문제가 발생할 수 있습니다. 데이터베이스 액세스를 제어할 경우에는 통합 보안이라고도 하는 Windows 인증을 사용하는 쪽이 더 안전합니다. 자세한 내용은 연결 정보 보호를 참조하세요.

  4. 데이터베이스 개체를 선택하라는 메시지가 표시되면 CustomersOrders 테이블을 선택하고 생성된 데이터 세트의 이름을 NorthwindDataSet으로 지정합니다.

데이터 소스에 바인딩

System.Windows.Forms.BindingSource 구성 요소는 애플리케이션의 데이터 원본에 대한 균일한 인터페이스를 제공합니다. 데이터 소스에 바인딩은 코드 숨김 파일에서 구현됩니다.

데이터 소스에 바인딩하려면

  1. MainWindow.xaml.vb 또는 MainWindow.xaml.cs라는 코드 숨김 파일을 엽니다.

  2. 다음 코드를 MainWindow 클래스 정의에 복사합니다.

    이 코드는 데이터베이스에 연결된 BindingSource 구성 요소와 관련 도우미 클래스를 선언합니다.

    private System.Windows.Forms.BindingSource nwBindingSource;
    private NorthwindDataSet nwDataSet;
    private NorthwindDataSetTableAdapters.CustomersTableAdapter customersTableAdapter =
        new NorthwindDataSetTableAdapters.CustomersTableAdapter();
    private NorthwindDataSetTableAdapters.OrdersTableAdapter ordersTableAdapter =
        new NorthwindDataSetTableAdapters.OrdersTableAdapter();
    
    Private nwBindingSource As System.Windows.Forms.BindingSource
    Private nwDataSet As NorthwindDataSet
    Private customersTableAdapter As New NorthwindDataSetTableAdapters.CustomersTableAdapter()
    Private ordersTableAdapter As New NorthwindDataSetTableAdapters.OrdersTableAdapter()
    
  3. 다음 코드를 생성자에 복사합니다.

    이 코드는 BindingSource 구성 요소를 만들고 초기화합니다.

    public MainWindow()
    {
        InitializeComponent();
    
        // Create a DataSet for the Customers data.
        this.nwDataSet = new NorthwindDataSet();
        this.nwDataSet.DataSetName = "nwDataSet";
    
        // Create a BindingSource for the Customers data.
        this.nwBindingSource = new System.Windows.Forms.BindingSource();
        this.nwBindingSource.DataMember = "Customers";
        this.nwBindingSource.DataSource = this.nwDataSet;
    }
    
    Public Sub New()
        InitializeComponent()
    
        ' Create a DataSet for the Customers data.
        Me.nwDataSet = New NorthwindDataSet()
        Me.nwDataSet.DataSetName = "nwDataSet"
    
        ' Create a BindingSource for the Customers data.
        Me.nwBindingSource = New System.Windows.Forms.BindingSource()
        Me.nwBindingSource.DataMember = "Customers"
        Me.nwBindingSource.DataSource = Me.nwDataSet
    
    End Sub
    
  4. MainWindow.xaml을 엽니다.

  5. 디자인 뷰 또는 XAML 뷰에서 Window 요소를 선택합니다.

  6. 속성 창에서 이벤트 탭을 클릭합니다.

  7. Loaded 이벤트를 두 번 클릭합니다.

  8. Loaded 이벤트 처리기에 다음 코드를 복사합니다.

    이 코드는 BindingSource 구성 요소를 데이터 컨텍스트로 할당하고 CustomersOrders 어댑터 개체를 채웁니다.

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        // Fill the Customers table adapter with data.
        this.customersTableAdapter.ClearBeforeFill = true;
        this.customersTableAdapter.Fill(this.nwDataSet.Customers);
    
        // Fill the Orders table adapter with data.
        this.ordersTableAdapter.Fill(this.nwDataSet.Orders);
    
        // Assign the BindingSource to
        // the data context of the main grid.
        this.mainGrid.DataContext = this.nwBindingSource;
    
        // Assign the BindingSource to
        // the data source of the list box.
        this.listBox1.ItemsSource = this.nwBindingSource;
    
        // Because this is a master/details form, the DataGridView
        // requires the foreign key relating the tables.
        this.dataGridView1.DataSource = this.nwBindingSource;
        this.dataGridView1.DataMember = "FK_Orders_Customers";
    
        // Handle the currency management aspect of the data models.
        // Attach an event handler to detect when the current item
        // changes via the WPF ListBox. This event handler synchronizes
        // the list collection with the BindingSource.
        //
    
        BindingListCollectionView cv = CollectionViewSource.GetDefaultView(
            this.nwBindingSource) as BindingListCollectionView;
    
        cv.CurrentChanged += new EventHandler(WPF_CurrentChanged);
    }
    
    Private Sub Window_Loaded( _
    ByVal sender As Object, _
    ByVal e As RoutedEventArgs)
    
        ' Fill the Customers table adapter with data.
        Me.customersTableAdapter.ClearBeforeFill = True
        Me.customersTableAdapter.Fill(Me.nwDataSet.Customers)
    
        ' Fill the Orders table adapter with data.
        Me.ordersTableAdapter.Fill(Me.nwDataSet.Orders)
    
        ' Assign the BindingSource to 
        ' the data context of the main grid.
        Me.mainGrid.DataContext = Me.nwBindingSource
    
        ' Assign the BindingSource to 
        ' the data source of the list box.
        Me.listBox1.ItemsSource = Me.nwBindingSource
    
        ' Because this is a master/details form, the DataGridView
        ' requires the foreign key relating the tables.
        Me.dataGridView1.DataSource = Me.nwBindingSource
        Me.dataGridView1.DataMember = "FK_Orders_Customers"
    
        ' Handle the currency management aspect of the data models.
        ' Attach an event handler to detect when the current item 
        ' changes via the WPF ListBox. This event handler synchronizes
        ' the list collection with the BindingSource.
        '
    
        Dim cv As BindingListCollectionView = _
            CollectionViewSource.GetDefaultView(Me.nwBindingSource)
    
        AddHandler cv.CurrentChanged, AddressOf WPF_CurrentChanged
    
    End Sub
    
  9. 다음 코드를 MainWindow 클래스 정의에 복사합니다.

    이 메서드는 CurrentChanged 이벤트를 처리하고 데이터 바인딩의 현재 항목을 업데이트합니다.

    // This event handler updates the current item
    // of the data binding.
    void WPF_CurrentChanged(object sender, EventArgs e)
    {
        BindingListCollectionView cv = sender as BindingListCollectionView;
        this.nwBindingSource.Position = cv.CurrentPosition;
    }
    
    ' This event handler updates the current item 
    ' of the data binding.
    Private Sub WPF_CurrentChanged(ByVal sender As Object, ByVal e As EventArgs)
        Dim cv As BindingListCollectionView = sender
        Me.nwBindingSource.Position = cv.CurrentPosition
    End Sub
    
  10. F5를 눌러 애플리케이션을 빌드 및 실행합니다.

참고 항목