【问题标题】:C# - DataGridView master-detail with DataGridViewComboBoxColumnC# - 带有 DataGridViewComboBoxColumn 的 DataGridView 主从细节
【发布时间】:2017-10-27 15:16:10
【问题描述】:

我对本应简单的事情感到很迷茫。

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

我将表的列表 DataTable 绑定到一个 DataGridView,并将列的列表 DataTable 绑定到主从模式下的第二个 DataGridView。第一个 DataSet 一切正常。

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

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

知道如何将主网格中的行选择链接到组合框吗?

我希望问题足够清楚, 感谢您的帮助!

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

    }
}

【问题讨论】:

    标签: c# winforms datagridview master-detail datagridcomboboxcolumn


    【解决方案1】:

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

    正如预期的那样,答案很简单。我在这篇文章中找到了灵感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"]);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      相关资源
      最近更新 更多