使用 FK(主从架构)绑定 DataGridView,但允许在 VS 编辑器中自定义列(C# - Winform)

Bind DataGridView with FK (Master-Slave architecture), but allowing column customization at VS Editor (C# - Winform)

数据库中的数据模型实现了一种主从架构,该架构在系统中呈现为带有 WinForm 的多个控件,其中包含用于 MasterTable 的多个控件,以及用于 Slave 的 Datagridview。 MasterTable 字段的所有控件都通过 BindingSource 组件进行绑定,而 SlaveTable 的 Datagridview 使用其自己的 BingindSource 作为 Fk 约束;通过这样做,用户可以通过 MasterTable 的绑定“位置”浏览 MasterTable 的记录,这样主控件会随着记录的数据更新,并且 Datagridview 也会根据 MasterTable 的 Pk 进行更新,这要归功于Fk 约束(作为 DataRelation 实现并添加到 MasterTable 的数据集中,因此出现在它的 BindingSource 中)。

查看网络和论坛 (),我发现主要控件可以通过编程方式与 DataBinding.Add() 绑定如果我愿意,即为文本框显示的文本指定格式,如下所示:

......

mainBind = new BindingSource();
slaveBind = new BindingSource();

mainBind.DataSource = mainDS;
mainBind.DataMember = "MasterTable";
slaveBind.DataSource = mainBind;
slaveBind.DataMember = "idFk"; //defined as DataRelation between Master-Slave tables

DataGrid.DataSource = slaveBind; 

Text1.DataBindings.Add("Text", mainBind, "field1", true, DataSourceUpdateMode.OnPropertyChanged, 19, "$##.00");                     
Text2.DataBindings.Add("Text", mainBind, "field2", true, DataSourceUpdateMode.OnPropertyChanged, DateTime.Now, "dd/MM/yyyy");

.....

通过这种方法,系统可以正常工作。

现在,据我所知,如果您不愿意使用例如 DataSource 通过向导(或 Entity Framework)。这是真的吗?

另一方面(这里是我真正的问题),通过将 Datagridview 绑定到 slaveBind,它是 Fk 的成员all SlaveTable 中的字段实际上已加载并显示,因此,如果我需要对其进行操作(例如使某些列不可见),我需要修改 SELECT 子句或以编程方式修改每一列(其中包括诸如对齐或显示格式),如下:

.....

DataGrid.Columns[0].Visible = false; //field1
DataGrid.Columns[1].Visible = false; //field2
DataGrid.Columns[2].Visible = false; //field3

DataGrid.Columns[3].Width = 184; //field4
DataGrid.Columns[3].DefaultCellStyle.Format = "N1";

.....

所以,如果我想要另一种方法,比如通过 VS 编辑器将自己的列添加到 Datagridview,然后绑定它们,我需要删除 fk 的绑定源才能工作(如果没有,自动数据负载优先);因此,我也失去了将 MasterTable 的 Pk 与 Datagridview 中显示的数据联系起来的可能性。

是否可以避免在这种情况下以编程方式自定义每个 Datagridview 的列?

非常感谢任何愿意支持这个问题的人。

p.s。不久前在 YouTube 上看到一个视频,它实现了主从架构,每次遍历 MasterTable 记录时,清理和重新填充 Datagridview:这是唯一的解决方案吗?

因此,在查找了一些相关但不完全是我的问题之后(我试图将我的第一个 Datagridview 的列配置为 ComboBoxColumn - ()(source2) -),我发现它是可以在 VS 设计器中添加列,并且 您已经在设计器中配置了所有列(如数字格式、文本对齐方式等)后,您可以以编程方式绑定每个列,并且 就这样,就可以用Fk的BindingSource绑定Datagridview了(p.s。重要的是设置Datagridview的AutoGenerateColumns 属性 = false).

换句话说;当 slaveBind 成为 DatagridView 的数据源时,它允许 DatagridView 查看 MasterTable 的 SlaveTable 的所有字段! (多亏了它的 DataRelation 成员 - 又名 Fk -),同时保持 Datagridview 的数据与 MasterTable 的 Pk 相关联,这是正在寻找的主要行为。

所以,为了完成,这里是我使用的代码:

DataGridViewComboBoxColumn dgComboBox = new DataGridViewComboBoxColumn();

DataRelation relMPkToSId = new DataRelation("idFk", mainDS.Tables["MasterTable"].Columns["id_pk"], slaveDS.Tables["SlaveTable"].Columns["idPk"]);
mainDS.Relations.Add(relMPkToSId);

mainBind = new BindingSource();
slaveBind = new BindingSource();

mainBind.DataSource = mainDS;
mainBind.DataMember = "MasterTable";
slaveBind.DataSource = mainBind;
slaveBind.DataMember = "idFk"; //defined as DataRelation between Master-Slave tables

//Bind the Form's controls to the MasterTable's fields
myText1.DataBindings.Add("Text", mainBind, "masterField1", true, DataSourceUpdateMode.OnPropertyChanged, 19, "$##.00");                     
myText2.DataBindings.Add("Text", mainBind, "masterField2", true, DataSourceUpdateMode.OnPropertyChanged, DateTime.Now, "dd/MM/yyyy");

.....

myDataGrid.AutoGenerateColumns = false; //important
// configure ComboBoxColumn
dgComboBox.DataSource = comboDS.Tables["myCatalog1"]; //another DS which provides the ComboBox datalist
dgComboBox.DisplayMember = "displayName";
dgComboBox.ValueMember = "internal_id";
dgComboBox.HeaderText = "Title:";
dgComboBox.DataPropertyName = "slaveField1";  //target field at SlaveTable where the the selected ComboBox value is stored
myDataGrid.Columns.Insert(0, dgComboBox); //insert the ComboBoxColumn at the Datagridview's first position
myDataGrid.Columns[0].Name = "dgColumn1"; //give the ComboBoxColumn a reference name
myDataGrid.Columns["dgColumn1"].Width = 184; //configure the ComboBox's width                    
myDataGrid.Columns["dgColumn1"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft; //configure the ComboBox's alignment

//Bind the rest of the columns generated at the VS Designer
myDataGrid.Columns["column2"].DataPropertyName = "slaveField2";
myDataGrid.Columns["column3"].DataPropertyName = "slavefield3";

.....

myDataGrid.DataSource = slaveBind; 

我希望这个结果对我相同情况下的其他人有所帮助。 此致,