How to: Create a Master/Detail Form Using Two Windows Forms DataGridView Controls

The following code example creates a master/detail form using two DataGridView controls bound to two BindingSource components. The data source is a DataSet that contains the Customers and Orders tables from the Northwind SQL Server sample database along with a DataRelation that relates the two through the CustomerID column.

One BindingSource is bound to the parent Customers table in the data set. This data is displayed in the master DataGridView control. The other BindingSource is bound to the first data connector. The DataMember property of the second BindingSource is set to the DataRelation name. This causes the associated detail DataGridView control to display the rows of the child Orders table that correspond to the current row in the master DataGridView control.

For a complete explanation of this code example, see Walkthrough: Creating a Master/Detail Form Using Two Windows Forms DataGridView Controls.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

public class Form1 : System.Windows.Forms.Form
    private DataGridView masterDataGridView = new DataGridView();
    private BindingSource masterBindingSource = new BindingSource();
    private DataGridView detailsDataGridView = new DataGridView();
    private BindingSource detailsBindingSource = new BindingSource();

    public static void Main()
        Application.Run(new Form1());

    // Initializes the form.
    public Form1()
        masterDataGridView.Dock = DockStyle.Fill;
        detailsDataGridView.Dock = DockStyle.Fill;

        SplitContainer splitContainer1 = new SplitContainer();
        splitContainer1.Dock = DockStyle.Fill;
        splitContainer1.Orientation = Orientation.Horizontal;

        this.Load += new System.EventHandler(Form1_Load);
        this.Text = "DataGridView master/detail demo";

    private void Form1_Load(object sender, System.EventArgs e)
        // Bind the DataGridView controls to the BindingSource
        // components and load the data from the database.
        masterDataGridView.DataSource = masterBindingSource;
        detailsDataGridView.DataSource = detailsBindingSource;

        // Resize the master DataGridView columns to fit the newly loaded data.

        // Configure the details DataGridView so that its columns automatically
        // adjust their widths when the data changes.
        detailsDataGridView.AutoSizeColumnsMode = 

    private void GetData()
            // Specify a connection string. Replace the given value with a 
            // valid connection string for a Northwind SQL Server sample
            // database accessible to your system.
            String connectionString =
                "Integrated Security=SSPI;Persist Security Info=False;" +
                "Initial Catalog=Northwind;Data Source=localhost";
            SqlConnection connection = new SqlConnection(connectionString);

            // Create a DataSet.
            DataSet data = new DataSet();
            data.Locale = System.Globalization.CultureInfo.InvariantCulture;

            // Add data from the Customers table to the DataSet.
            SqlDataAdapter masterDataAdapter = new
                SqlDataAdapter("select * from Customers", connection);
            masterDataAdapter.Fill(data, "Customers");

            // Add data from the Orders table to the DataSet.
            SqlDataAdapter detailsDataAdapter = new
                SqlDataAdapter("select * from Orders", connection);
            detailsDataAdapter.Fill(data, "Orders");

            // Establish a relationship between the two tables.
            DataRelation relation = new DataRelation("CustomersOrders",

            // Bind the master data connector to the Customers table.
            masterBindingSource.DataSource = data;
            masterBindingSource.DataMember = "Customers";

            // Bind the details data connector to the master data connector,
            // using the DataRelation name to filter the information in the 
            // details table based on the current row in the master table. 
            detailsBindingSource.DataSource = masterBindingSource;
            detailsBindingSource.DataMember = "CustomersOrders";
        catch (SqlException)
            MessageBox.Show("To run this example, replace the value of the " +
                "connectionString variable with a connection string that is " +
                "valid for your system.");

This example requires:

  • References to the System, System.Data, System.Windows.Forms, and System.XML assemblies.

For information about building this example from the command line for Visual Basic or Visual C#, see Building from the Command Line (Visual Basic) or Command-line Building With csc.exe. You can also build this example in Visual Studio by pasting the code into a new project. For more information, see How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio and How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio and How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio and How to: Compile and Run a Complete Windows Forms Code Example Using Visual Studio.

Storing sensitive information, such as a password, within the connection string can affect the security of your application. Using Windows Authentication (also known as integrated security) is a more secure way to control access to a database. For more information, see Protecting Connection Information (ADO.NET).

Community Additions