C# - 使用DataGridViewComboBoxColumn的DataGridView主细节

时间:2017-10-27 15:16:10

标签: c# winforms datagridview master-detail datagridcomboboxcolumn

我完全迷失了一些本来应该很简单的东西。

我有两个DataSet,都包含两个DataTable。每个DataTable都是我从两个数据库的模式中读取的表名和列名的列表。

我将表的列表DataTable绑定到DataGridView,并将列的DataTable列为主 - 详细信息模式中的第二个DataGridView。对于第一个DataSet,一切正常。

然后我将两个DataGridViewComboBoxColumn添加到每个DataGridView并将这些列的ComboBox绑定到第二个DataSet。

从主DataGridView中选择一行时,将使用与所选行相关的列填充详细信息DataGridView。 但是,只有在选择主DataGridView中的DataGridViewComboBoxColumn时,详细DataGridView中的DataGridViewComboBoxColumn才会更新。

知道如何将主网格中的行选择链接到ComboBox?

我希望这个问题很清楚, 谢谢你的帮助!

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

namespace MasterDetailTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private DataGridView dataGridView1 = new DataGridView();
        private DataSet dataSet1 = new DataSet();
        private BindingSource bindingSourceTables1 = new BindingSource();
        private BindingSource bindingSourceColumns1 = new BindingSource();

        private DataGridView dataGridView2 = new DataGridView();
        private DataSet dataSet2 = new DataSet();
        private BindingSource bindingSourceTables2 = new BindingSource();
        private BindingSource bindingSourceColumns2 = new BindingSource();


        private void Form1_Load(object sender, EventArgs e)
        {
            SetGrids(dataGridView1, dataGridView2);

            dataGridView1.DataSource = bindingSourceTables1;
            dataGridView2.DataSource = bindingSourceColumns1;

            // DataSet1
            DataTable tables1 = new DataTable("tables1");
            tables1.Columns.Add(new DataColumn("TABLE_NAME", typeof(string)));
            tables1.Columns.Add(new DataColumn("TABLE_NAME2", typeof(string))); //Map DataSet2's table name to DataSet1's table name

            DataTable columns1 = new DataTable("columns1");
            columns1.Columns.Add(new DataColumn("TABLE_NAME", typeof(string)));
            columns1.Columns.Add(new DataColumn("COLUMN_NAME", typeof(string)));
            columns1.Columns.Add(new DataColumn("COLUMN_NAME2", typeof(string)));   //Map DataSet2's column name to DataSet1's column name

            dataSet1.Tables.Add(tables1);
            dataSet1.Tables.Add(columns1);

            tables1.PrimaryKey = new DataColumn[] { tables1.Columns["TABLE_NAME"] };
            columns1.PrimaryKey = new DataColumn[] { columns1.Columns["TABLE_NAME"], columns1.Columns["COLUMN_NAME"] };

            dataSet1.Relations.Add(new DataRelation("TablesColumns", dataSet1.Tables["tables1"].Columns["TABLE_NAME"], dataSet1.Tables["columns1"].Columns["TABLE_NAME"]));

            bindingSourceTables1.DataSource = dataSet1;
            bindingSourceTables1.DataMember = "tables1";

            bindingSourceColumns1.DataSource = bindingSourceTables1;
            bindingSourceColumns1.DataMember = "TablesColumns";

            // DataSet2
            DataTable tables2 = new DataTable("tables2");
            tables2.Columns.Add(new DataColumn("TABLE_NAME2", typeof(string)));

            DataTable columns2 = new DataTable("columns2");
            columns2.Columns.Add(new DataColumn("TABLE_NAME", typeof(string)));
            columns2.Columns.Add(new DataColumn("COLUMN_NAME2", typeof(string)));

            dataSet2.Tables.Add(tables2);
            dataSet2.Tables.Add(columns2);

            tables2.PrimaryKey = new DataColumn[] { tables2.Columns["TABLE_NAME2"] };
            columns2.PrimaryKey = new DataColumn[] { columns2.Columns["TABLE_NAME"], columns2.Columns["COLUMN_NAME2"] };

            dataSet2.Relations.Add(new DataRelation("TablesColumns", dataSet2.Tables["tables2"].Columns["TABLE_NAME2"], dataSet2.Tables["columns2"].Columns["TABLE_NAME"]));

            bindingSourceTables2.DataSource = dataSet2;
            bindingSourceTables2.DataMember = "tables2";

            bindingSourceColumns2.DataSource = bindingSourceTables2;
            bindingSourceColumns2.DataMember = "TablesColumns";

            DataGridViewComboBoxColumn dccTables = new DataGridViewComboBoxColumn()
            {
                DataSource = bindingSourceTables2,
                DataPropertyName = "TABLE_NAME2",
                DisplayMember = "TABLE_NAME2",
                ValueMember = "TABLE_NAME2",
                HeaderText = "TABLE_NAME2",
                Name = "TABLE_NAME2"
            };

            dataGridView1.Columns.Remove("TABLE_NAME2");
            dataGridView1.Columns.Add(dccTables);

            DataGridViewComboBoxColumn dccColumns = new DataGridViewComboBoxColumn()
            {
                DataSource = bindingSourceColumns2,
                DataPropertyName = "COLUMN_NAME2",
                DisplayMember = "COLUMN_NAME2",
                ValueMember = "COLUMN_NAME2",
                HeaderText = "COLUMN_NAME2",
                Name = "COLUMN_NAME2"
            };

            dataGridView2.Columns.Remove("COLUMN_NAME2");
            dataGridView2.Columns.Add(dccColumns);

            //Data
            CreateData();

        }

        private void CreateData()
        {
            for (int i = 0; i < 3; i++)
            {
                DataRow dt = dataSet1.Tables["tables1"].NewRow();
                dt["TABLE_NAME"] = "TableName" + i;
                dataSet1.Tables["tables1"].Rows.Add(dt);

                for (int j = 0; j < 5; j++)
                {
                    DataRow dc = dataSet1.Tables["columns1"].NewRow();
                    dc["TABLE_NAME"] = "TableName" + i;
                    dc["COLUMN_NAME"] = "ColumnName" + i + j;
                    dataSet1.Tables["columns1"].Rows.Add(dc);
                }
            }
            for (int i = 0; i < 3; i++)
            {
                DataRow dt = dataSet2.Tables["tables2"].NewRow();
                dt["TABLE_NAME2"] = "TableName" + i;
                dataSet2.Tables["tables2"].Rows.Add(dt);

                for (int j = 0; j < 5; j++)
                {
                    DataRow dc = dataSet2.Tables["columns2"].NewRow();
                    dc["TABLE_NAME"] = "TableName" + i;
                    dc["COLUMN_NAME2"] = "ColumnName" + i + j;
                    dataSet2.Tables["columns2"].Rows.Add(dc);
                }
            }
        }

        private void SetGrids(DataGridView dgv1, DataGridView dgv2)
        {
            dgv1.Width = 400;
            dgv2.Width = 400;
            dgv2.Top = dgv1.Height;

            this.Controls.Add(dataGridView1);
            this.Controls.Add(dataGridView2);
        }

    }
}

1 个答案:

答案 0 :(得分:0)

这个问题困扰了我好几天,当我终于提出这个问题时......我找到了答案。

正如所料,答案很简单。我在本文How to: Ensure Multiple Controls Bound to the Same Data Source Remain Synchronized

中找到了灵感

我的解决方案是在bindingSourceTables1的CurrentChanged事件中添加此代码:

    private void bindingSourceTables1_CurrentChanged(object sender, EventArgs e)
    {
        bindingSourceTables2.Position = bindingSourceTables2.Find("TABLE_NAME2", ((DataRowView)((BindingSource)sender).Current).Row["TABLE_NAME2"]);
    }