c# - 创建从数据源映射值的 DataGridView 列
问题描述
我有一个DataTable
,其中包含一些数据,例如。像这样:
| id | name | type_id |
+-----+-------+---------+
| 0 | joe | 156 |
| 1 | alice | 23 |
中的数据DataTable
来自 SQL-ish 数据库。我也有DataGridView
,应该显示以下内容:
| name | type_name |
+-------+-----------+
| joe | admin |
| alice | user |
我有办法查找type_id
. type_name
我添加了一个DataGridViewComboBoxColumn
,当它改变时,我更新type_id
基础表中的:
private void cellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// find the cell
DataGridViewCell cell = dataGridView[e.ColumnIndex, e.RowIndex];
string columnName = dataGridView.Columns[e.ColumnIndex]?.Name ?? "";
// check if combo cell is in this column for sure
if(cell is DataGridViewComboBoxCell comboCell)
{
// Only user type is subject to this event
if(columnName == "type_name")
{
// BIG NOTE: THE LOOKUP HERE COULD (and is) BE MORE COMPLEX!
// This is just an example for stack overflow
object cellVal = comboCell.Value;
// Only numeric values
// Combobox displays string names, but contains numeric values
if(cellVal!=null && IsNumber(cellVal))
{
// change the underlying datatable, not the grid view
dataTable.Rows[e.RowIndex]["type_id"] = cellVal;
}
}
}
}
但我也想有一个反之亦然的版本。加载时DataGridView
,组合框列中的值为空。如何编写一段代码,将值从 DataTable 列映射到DataGridView 列。
注意:在我的真实场景中,映射比数字->字符串更复杂。涉及多个值。因此,必须真正创建新列!
解决方案
目前尚不清楚“type_id”映射到“type_name”的值。也就是说,目前如果“type_id”是int
156,那么“type_name”就是string
“admin”。“type_id”中是否还有其他数字也会产生“admin”?</p>
如果它是一对一关系,那么DataTable
具有此映射的 a 将适用于组合框,并且您可以将组合框列直接映射到网格DataTable.
示例,如果存在一对一关系,则组合框的DataTable
for 将有两个属性,一个int
用于“type_id”,一个string
用于“type_name”。</p>
使用正确的映射填充表格,然后设置组合框DataSource
以指向该表格。将组合框设置DataPropertyName
为“type_id”会将此列映射到网格中的相同列名DataSource.
使用这种方法,用户将在组合框中看到“admin”“user”等......如果他们改变了它的值,DataTable
网格中的 将自动更新“ int
type_id”值。无需手动设置值。如果组合框设置正确,则此方法有效。
下面是一个例子。
如果存在一对多关系,那么我可以发布另一种解决方案。以下是上述内容的示例。
表格有两个DataGridView
s。两个网格都使用相同DataTable
的DataSource.
顶部网格,只显示我们想要的两列……“name”和“type_id”。“type_id”列是组合框列,将为“type_id”显示正确的“type_name” int
。</p>
顶部网格CurrentCellDirtyStateChanged
事件被连接以更新DataSource
底部网格以显示int
当用户更改组合框单元格值时“type_id”值会自动更改。
我希望这是有道理的。
DataTable dataTable;
DataTable comboData;
public Form2() {
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e) {
dataTable = GetTable();
FillTable(dataTable);
FillComboTable();
SetGridColumns(dataGridView1);
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = dataTable;
dataGridView2.DataSource = dataTable;
}
private DataTable GetTable() {
DataTable dt = new DataTable();
dt.Columns.Add("id", typeof(int));
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("type_id", typeof(int));
return dt;
}
private void FillTable(DataTable dt) {
dt.Rows.Add(0, "joe", 156);
dt.Rows.Add(1, "alice", 23);
dt.Rows.Add(2, "mark", 0);
dt.Rows.Add(3, "sally", 44);
dt.Rows.Add(4, "gabe", 133);
}
private DataTable GetComboTable() {
DataTable dt = new DataTable();
dt.Columns.Add("value", typeof(int));
dt.Columns.Add("name", typeof(string));
return dt;
}
private void FillComboTable() {
comboData = GetComboTable();
comboData.Rows.Add(156, "admin");
comboData.Rows.Add(23, "user");
comboData.Rows.Add(44, "database");
comboData.Rows.Add(133, "system");
comboData.Rows.Add(0, " ");
}
private void SetGridColumns(DataGridView dgv) {
DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
col1.HeaderText = "name";
col1.Name = "name";
col1.DataPropertyName = "name";
dgv.Columns.Add(col1);
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn {
HeaderText = "type_id",
Name = "type_id",
DataPropertyName = "type_id",
DataSource = comboData,
DisplayMember = "name",
ValueMember = "value"
};
dgv.Columns.Add(combo);
}
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) {
MessageBox.Show("Data Error: " + e.Exception.Message);
}
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e) {
if (dataGridView1.IsCurrentCellDirty) {
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
dataGridView2.DataSource = null;
dataGridView2.DataSource = dataTable;
}
}
推荐阅读
- c - 写入二维数组的问题,嵌入式 C
- three.js - 使用physijs给三个.js添加物理效果的问题?
- c - STM32F446RE 板上的应用内程序从用户引导加载程序跳转到用户应用程序,反之亦然
- c# - 将 .NET Core 多目标添加到 .NET Framework 库
- javascript - 使用 javascript 将模式中的输入添加到新表行
- ms-access-2013 - 我想在同一张表的另一个字段中获取一个完整字段(数字类型)的总和
- reactjs - Semantic-UI React Dropdown - 使用 Enter 键
- python - Python:曲线拟合看起来很乱
- swift - Swift UI - 锁定和解锁 ScrollView
- python - 在 python 上安装 nltk