다음을 통해 공유


연습: 혼합 응용 프로그램에서 데이터 바인딩

업데이트: 2010년 8월

데이터 소스를 컨트롤에 바인딩하는 작업은 Windows Forms과 WPF 중에 무엇을 사용 중이건 사용자가 내부 데이터에 액세스할 수 있도록 하기 위해 필수적입니다. 이 연습은 Windows Forms 및 WPF 컨트롤을 모두 포함하는 혼합 응용 프로그램에서 데이터 바인딩을 사용하는 방법을 보여 줍니다.

이 연습에서 수행할 작업은 다음과 같습니다.

  • 프로젝트 만들기

  • 데이터 템플릿 정의

  • 폼 레이아웃 지정

  • 데이터 바인딩 지정

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

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

  • 데이터 소스에 바인딩

이 연습에서 설명하는 작업의 전체 코드 목록은 Data Binding in Hybrid Applications 샘플을 참조하십시오.

연습을 마치면 혼합 응용 프로그램에서의 데이터 바인딩 기능을 이해할 수 있게 됩니다.

사전 요구 사항

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

  • Visual Studio 2010.

  • 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. Name 속성을 할당하여 기본 Grid 요소 mainGrid를 명명합니다.

        <Grid x:Name="mainGrid">
    

데이터 템플릿 정의

고객의 마스터 목록은 ListBox 컨트롤에 표시됩니다. 다음 코드 예제는 ListBox 컨트롤의 시각적 트리를 제어하는 ListItemsTemplate이라는 DataTemplate 개체를 정의합니다. 이 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 컨트롤에 표시됩니다. 첨부된 ListItemsTemplate은 TextBlock 컨트롤을 데이터베이스의 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>
    

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

선택한 고객에 해당하는 주문은 dataGridView1이라는 System.Windows.Forms.DataGridView 컨트롤에 표시됩니다. 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 데이터베이스에 대한 연결을 만듭니다. 자세한 내용은 방법: 데이터베이스의 데이터에 연결을 참조하십시오.

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

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

데이터 소스에 바인딩

System.Windows.Forms.BindingSource 구성 요소는 응용 프로그램의 데이터 소스에 일관된 인터페이스를 제공합니다. 데이터 소스에 바인딩하는 작업은 코드 숨김 파일에서 구현됩니다.

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

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

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

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

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

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

    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
    
    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;
    }
    
  4. MainWindow.xaml을 엽니다.

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

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

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

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

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

    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
    
    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);
    }
    
  9. 다음 코드를 MainWindow 클래스 정의에 복사합니다.

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

    ' 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
    
    // 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;
    }
    
  10. F5 키를 눌러 응용 프로그램을 빌드 및 실행합니다.

참고 항목

참조

ElementHost

WindowsFormsHost

개념

연습: WPF에서 Windows Forms 복합 컨트롤 호스팅

연습: Windows Forms에서 WPF 복합 컨트롤 호스팅

기타 리소스

WPF Designer

Data Binding in Hybrid Applications 샘플

변경 기록

날짜

변경 내용

이유

2010년 8월

Visual Studio 2010에 대한 내용을 업데이트했습니다.

고객 의견