Walkthrough: Binding to Data in Hybrid Applications


Binding a data source to a control is essential for providing users with access to underlying data, whether you are using Windows Forms or WPF. This walkthrough shows how you can use data binding in hybrid applications that include both Windows Forms and WPF controls.

Tasks illustrated in this walkthrough include:

  • Creating the project.

  • Defining the data template.

  • Specifying the form layout.

  • Specifying data bindings.

  • Displaying data by using interoperation.

  • Adding the data source to the project.

  • Binding to the data source.

For a complete code listing of the tasks illustrated in this walkthrough, see Data Binding in Hybrid Applications Sample.

When you are finished, you will have an understanding of data binding features in hybrid applications.

You need the following components to complete this walkthrough:

  • Visual Studio 2010.

  • Access to the Northwind sample database running on Microsoft SQL Server.

To create and set up the project

  1. Create a WPF Application project named WPFWithWFAndDatabinding.

  2. In Solution Explorer, add references to the following assemblies.

    • WindowsFormsIntegration

    • System.Windows.Forms

  3. Open MainWindow.xaml in the WPF Designer.

  4. In the Window element, add the following Windows Forms namespaces mapping.

  5. Name the default Grid element mainGrid by assigning the Name property.

    	<Grid x:Name="mainGrid">

The master list of customers is displayed in a ListBox control. The following code example defines a DataTemplate object named ListItemsTemplate that controls the visual tree of the ListBox control. This DataTemplate is assigned to the ListBox control's ItemTemplate property.

To define the data template

  • Copy the following XAML into the Grid element's declaration.

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

The layout of the form is defined by a grid with three rows and three columns. Label controls are provided to identify each column in the Customers table.

To set up the Grid layout

  • Copy the following XAML into the Grid element's declaration.

    			<RowDefinition Height="Auto"/>
    			<RowDefinition Height="Auto"/>
    			<RowDefinition Height="Auto"/>
    			<ColumnDefinition Width="Auto"/>
    			<ColumnDefinition Width="Auto"/>
    			<ColumnDefinition Width="Auto"/>

To set up the Label controls

  • Copy the following XAML into the Grid element's declaration.

    		<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>

The master list of customers is displayed in a ListBox control. The attached ListItemsTemplate binds a TextBlock control to the ContactName field from the database.

The details of each customer record are displayed in several TextBox controls.

To specify data bindings

  • Copy the following XAML into the Grid element's declaration.

    The Binding class binds the TextBox controls to the appropriate fields in the database.

    		<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 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}"/>

The orders corresponding to the selected customer are displayed in a System.Windows.Forms.DataGridView control named dataGridView1. The dataGridView1 control is bound to the data source in the code-behind file. A WindowsFormsHost control is the parent of this Windows Forms control.

To display data in the DataGridView control

  • Copy the following XAML into the Grid element's declaration.

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

With Visual Studio, you can easily add a data source to your project. This procedure adds a strongly typed data set to your project. Several other support classes, such as table adapters for each of the chosen tables, are also added.

To add the data source

  1. From the Data menu, select Add New Data Source.

  2. In the Data Source Configuration Wizard, create a connection to the Northwind database by using a dataset. For more information, see How to: Connect to Data in a Database.

  3. When you are prompted by the Data Source Configuration Wizard, save the connection string as NorthwindConnectionString.

  4. When you are prompted to choose your database objects, select the Customers and Orders tables, and name the generated data set NorthwindDataSet.

The System.Windows.Forms.BindingSource component provides a uniform interface for the application's data source. Binding to the data source is implemented in the code-behind file.

To bind to the data source

  1. Open the code-behind file, which is named MainWindow.xaml.vb or MainWindow.xaml.cs.

  2. Copy the following code into the MainWindow class definition.

    This code declares the BindingSource component and associated helper classes that connect to the database.

        Private nwBindingSource As System.Windows.Forms.BindingSource
        Private nwDataSet As NorthwindDataSet
        Private customersTableAdapter As New NorthwindDataSetTableAdapters.CustomersTableAdapter()
        Private ordersTableAdapter As New NorthwindDataSetTableAdapters.OrdersTableAdapter()

  3. Copy the following code into the constructor.

    This code creates and initializes the BindingSource component.

        Public Sub New()
            ' 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. Open MainWindow.xaml.

  5. In Design view or XAML view, select the Window element.

  6. In the Properties window, click the Events tab.

  7. Double-click the Loaded event.

  8. Copy the following code into the Loaded event handler.

    This code assigns the BindingSource component as the data context and populates the Customers and Orders adapter objects.

        Private Sub Window_Loaded( _
        ByVal sender As Object, _
        ByVal e As RoutedEventArgs)
            ' Fill the Customers table adapter with data.
            Me.customersTableAdapter.ClearBeforeFill = True
            ' Fill the Orders table adapter with data.
            ' 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 = _
            AddHandler cv.CurrentChanged, AddressOf WPF_CurrentChanged
        End Sub

  9. Copy the following code into the MainWindow class definition.

    This method handles the CurrentChanged event and updates the current item of the data binding.

        ' 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. Press F5 to build and run the application.

WPF Designer
Data Binding in Hybrid Applications Sample
Walkthrough: Hosting a Windows Forms Composite Control in WPF
Walkthrough: Hosting a WPF Composite Control in Windows Forms