views:

1599

answers:

1

Hello,

I want to show a master / detail relationship using two datagridviews and DataRelation in C#.

The relation between the master and the detail table is an ID from type string (and there is no chance to change the ID to type integer).

It seems like the DataGridView is not able to update the detail view when changing the row in the master table.

Does anybody know if it is possible to achieve a master / detail view using a string ID and if yes, how? Or do I have to use an external DataGrid from another company?

Personally I don't see a difference in using a string instead of an integer. The only thing I can think of is that the grid cannot handle a master detail view using a string ID relation.

UPDATE: The issue is solved, the problem was that one relation was from type nchar and had blancs at the end of the string. Thanks for the help!

Here is an example, please create a new VS 2008 project and copy the code. Change the connection string and the datarelation:

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();

    [STAThreadAttribute()]
    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;
        splitContainer1.Panel1.Controls.Add(masterDataGridView);
        splitContainer1.Panel2.Controls.Add(detailsDataGridView);

        this.Controls.Add(splitContainer1);
        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;
        GetData();

        // Resize the master DataGridView columns to fit the newly loaded data.
        masterDataGridView.AutoResizeColumns();

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

    private void GetData()
    {
        try
        {
            // 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 =
                "";
            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",
                data.Tables["Customers"].Columns["strID"],
                data.Tables["Orders"].Columns["strID"]);
            data.Relations.Add(relation);

            // 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.");
        }
    }
}
A: 

I looked through your code and it looks basically OK. Please try to trim it a little further though.

But I find the Field Names "strId" a bit suspicious, is that really what the columns are called in the Database?

Tip: Put a break on the Relations.Add(relation) line and inspect the relation object carefully.

The code doesn't show where/how the bindinsource components are made, maybe they have some designtime properties set (Filter).

Henk Holterman