【问题标题】:Bind DataGridView with FK (Master-Slave architecture), but allowing column customization at VS Editor (C# - Winform)将 DataGridView 与 FK(主从架构)绑定,但允许在 VS 编辑器中自定义列(C# - Winform)
【发布时间】:2021-11-26 00:18:53
【问题描述】:

DB 中的 DataModel 实现了主从架构,该架构在系统中显示为带有多个 MasterTable 控件的 WinForm 和用于 Slave 的 Datagridview。 MasterTable字段的所有控件都通过BindingSource组件绑定,SlaveTable的Datagridview使用自己的BingindSource进行Fk约束;通过这样做,用户可以通过 MasterTable 的绑定“位置”浏览 MasterTable 的记录,从而使主控件使用记录的数据进行更新,并且 Datagridview 也基于 MasterTable 的 Pk 进行更新,这要归功于Fk 约束(实现为 DataRelation 并添加到 MasterTable 的 DataSet 中,因此出现在它的 BindingSource 中)。

查看网络和论坛 (like here),我发现如果我愿意,可以通过编程方式将主控件与 DataBinding.Add() 绑定,即给出格式到Textboxes显示的文本,如下:

......

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

.....

通过这种方法,系统可以按预期工作。

现在,据我了解,如果您不愿意通过向导(或实体框架)。这是真的吗?

另一方面(这里是我真正的问题),通过将 Datagridview 绑定到 slaveBind 并且它是 Fk 的成员所有来自 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 的列?

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

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

【问题讨论】:

    标签: c# visual-studio winforms datagridview master-slave


    【解决方案1】:

    所以,在寻找某种相关但不完全是我的问题之后(我试图将我的第一个 Datagridview 的列配置为 ComboBoxColumn - (source1)(source2) -),我发现它可以在 VS 设计器中添加列,您已经在设计器中配置了所有列(如数字格式、文本对齐等),您可以通过编程方式绑定每个列,就在这时,您可以将Datagridview 与Fk 的BindingSource 绑定(ps 设置Datagridview 的AutoGenerateColumns 属性=false 很重要)。

    换句话说;当 slaveBind 成为 DatagridView 的 DataSource 时,它​​允许 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; 
    
    

    我希望这个结果对我同样情况下的其他人有所帮助。 问候,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-04
      • 2010-11-14
      • 2022-11-01
      • 2021-10-04
      • 2011-07-17
      • 2012-08-13
      相关资源
      最近更新 更多