C # - мастер-деталь DataGridView с DataGridViewComboBoxColumn

Я совершенно потерялся в чем-то, что должно быть простым.

У меня есть два DataSet, оба содержат два DataTable. Каждый DataTable представляет собой список имен таблиц и имен столбцов, которые я читаю из схем двух баз данных.

Я привязываю список таблиц DataTable к DataGridView, а список столбцов DataTable - ко второму DataGridView в режиме мастер-детали. Для этого первого DataSet все работает нормально.

Затем я добавляю два DataGridViewComboBoxColumn к каждому DataGridView и привязываю ComboBox этих столбцов ко второму DataSet.

Когда вы выбираете строку в главном DataGridView, деталь DataGridView заполняется столбцами, относящимися к выбранной строке. Однако DataGridViewComboBoxColumn в детали DataGridView обновляется только тогда, когда выбран DataGridViewComboBoxColumn в главном DataGridView.

Есть идеи, как связать выделение строк в главной сетке с 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);
        }

    }
}

person wannabe    schedule 27.10.2017    source источник


Ответы (1)


Эта проблема не давала мне покоя в течение нескольких дней, и когда я наконец задал вопрос ... Я нашел ответ.

Как и ожидалось, ответ был легким. Я нашел вдохновение в этой статье Как обеспечить синхронизацию нескольких элементов управления, привязанных к одному источнику данных

Мое решение заключалось в том, чтобы добавить этот код в событие CurrentChanged привязкиSourceTables1:

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