C# - DataGridView 主从与 DataGridViewComboBoxColumn
C# - DataGridView master-detail with DataGridViewComboBoxColumn
我对一些本应很简单的东西感到迷茫。
我有两个数据集,都包含两个数据表。每个 DataTable 都是我从两个数据库的架构中读取的表名和列名的列表。
我在主从模式下将表的列表 DataTable 绑定到 DataGridView,将列的列表 DataTable 绑定到第二个 DataGridView。第一个数据集一切正常。
然后我向每个 DataGridView 添加两个 DataGridViewComboBoxColumn,并将这些列的 ComboBox 绑定到第二个 DataSet。
当您 select 主 DataGridView 中的一行时,详细 DataGridView 会填充与 selected 行相关的列。
但是,详细 DataGridView 中的 DataGridViewComboBoxColumn 仅在主 DataGridView 中的 DataGridViewComboBoxColumn 被 selected 时才会更新。
知道如何 link 主网格中的行 selection 到 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);
}
}
}
这个问题已经困扰我好几天了,当我终于提出这个问题时...我找到了答案。
不出所料,答案很简单。我在这篇文章中找到了灵感 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"]);
}
我对一些本应很简单的东西感到迷茫。
我有两个数据集,都包含两个数据表。每个 DataTable 都是我从两个数据库的架构中读取的表名和列名的列表。
我在主从模式下将表的列表 DataTable 绑定到 DataGridView,将列的列表 DataTable 绑定到第二个 DataGridView。第一个数据集一切正常。
然后我向每个 DataGridView 添加两个 DataGridViewComboBoxColumn,并将这些列的 ComboBox 绑定到第二个 DataSet。
当您 select 主 DataGridView 中的一行时,详细 DataGridView 会填充与 selected 行相关的列。 但是,详细 DataGridView 中的 DataGridViewComboBoxColumn 仅在主 DataGridView 中的 DataGridViewComboBoxColumn 被 selected 时才会更新。
知道如何 link 主网格中的行 selection 到 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);
}
}
}
这个问题已经困扰我好几天了,当我终于提出这个问题时...我找到了答案。
不出所料,答案很简单。我在这篇文章中找到了灵感 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"]);
}