【问题标题】:Bind datagrid to a table and display fields from parent tables将数据网格绑定到表并显示父表中的字段
【发布时间】:2012-07-10 03:54:45
【问题描述】:

在 WinForms 应用程序的以下场景中绑定数据网格的最佳策略是什么。 假设,我有一个带有表格的强类型数据集:

Table1 (T1_ID, T1_VALUE) <--* Table2 (T2_ID, T1_ID, T2_VALUE) <--* Table3(T3_ID, T2_ID, T3_VALUE)

我想将数据网格绑定到 Table3,并显示 Table2 和 Table1 中的字段,并能够过滤,按所有列排序:

T3_VALUE | T2_VALUE | T1_VALUE

在这种情况下,常见的绑定方法是什么?

我看到以下替代方案:

  1. 添加计算列:
    Table2.T1_VALUE = PARENT(T2_T1).T1_VALUE
    Table3.T2_VALUE = PARENT(T3_T2).T2_VALUE
    Table3.T1_VALUE = PARENT(T3_T2).T1_VALUE
    其中 T2_T1、T3_T2 - 关系名称。
    这似乎是正确的方法,但我担心干净的数据模型会污染仅用于 UI 目的的冗余计算列(在代码的其他地方我仍会使用 Table3Row.Table2Row.Table1Row.T1_VALUE

    李>
  2. 使用 Linq 查询数据集并从不同表中获取列 但是在这种情况下,网格将无法将数据写入table3并进行排序。

  3. 将网格绑定到 Table3 并处理呈现单元格的事件,并从那里的父表输出值。 网格可以写入Table3,但是不能排序(我用的是syncfusion网格,但我觉得没什么区别)

  4. 实现一个可以显示来自多个表的数据的视图,并更新主表。我没有朝这个方向挖掘,它似乎太复杂了。有可能吗?

正如我所指出的,使用计算列可以解决所有问题,而且似乎是最简单的解决方法。但也许有更优雅和正确的方法。

【问题讨论】:

  • I want to bind a datagrid to Table3, and display fields from Table2 and Table1, and have ability to filter, sort by all columns: --> 创建视图!!
  • 这在#4 中提到。我不确定这是否可能。

标签: .net vb.net winforms data-binding dataset


【解决方案1】:

使用 Syncfusion GridGroupingControl,UnboundFields 集合将帮助您轻松实现此要求。 Table3 可以绑定到网格,需要从其他 2 个表引用的字段可以作为 UnboundFields 添加到 GridGroupingControl。这些值可以通过处理 QueryValue 事件来填充。

//On Load of Windows Form
DataSet ds = new DataSet();
ds.Tables.AddRange(new DataTable[] { dt1, dt2, dt3 }); //dt1, dt2 and dt3 are Table1, Table2 and Table3 respectively
this.gridGroupingControl1.DataSource = ds.Tables[2]; // Table3 bounded
this.gridGroupingControl1.TableDescriptor.UnboundFields.Add("T1_VALUE"); // column from Table1
this.gridGroupingControl1.TableDescriptor.UnboundFields.Add("T2_VALUE"); // column from Table2
this.gridGroupingControl1.QueryValue += new Syncfusion.Grouping.FieldValueEventHandler(gridGroupingControl1_QueryValue);

如果您希望在运行时允许将修改后的数据保存在这些字段中,可以另外处理 SaveValue 事件,并且可以使用更新的值设置底层数据行(QueryValue 的反向事件代码)。

//Method Invoked to populate unbound fields with respective values
void gridGroupingControl1_QueryValue(object sender, Syncfusion.Grouping.FieldValueEventArgs e)
{
   if (e.Field.Name == "T1_VALUE")
      e.Value = dt1.Rows[e.Record.GetSourceIndex()][e.Field.Name];
   else if (e.Field.Name == "T2_VALUE")
      e.Value = dt2.Rows[e.Record.GetSourceIndex()][e.Field.Name];
}

这些未绑定的字段还支持排序和过滤。

【讨论】:

  • 这不是我想要的,但这可能有效。
【解决方案2】:

我经常从面向对象的角度来看待这些事情。我将创建一个具有您想要的所有属性的对象,并绑定到这些对象的集合。如果您想要两种方式的数据绑定,您可以使用 ObservableCollection 来允许网格获取对集合的更改并在对象的属性上实现 IPropertyChanged。通常,表 1 和表 2 中的属性只能在对象上读取。

【讨论】:

  • 我搜索了替代方法,发现了支持排序和过滤的 BindingList 的几个实现。但问题是常见的方法是什么。我只是不想重新发明一辆自行车。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 2015-08-07
  • 2011-01-31
  • 2017-05-14
  • 1970-01-01
  • 2011-01-01
  • 2016-04-30
相关资源
最近更新 更多