【问题标题】:Display rows from multiple DataTables in single DataGridView在单个 DataGridView 中显示来自多个 DataTables 的行
【发布时间】:2014-11-17 09:18:26
【问题描述】:

我继承了多个具有不同列名的数据表,这些数据表当前都显示在它们自己的 DataGridView 中。我想创建一个新的附加 DataGridView,将它们全部显示在一个 DataGridView 中。例如(非常简化):

public class DataTableA: DataTable
{
    public DataTableA()
    {
        this.Columns.Add("DateA", typeof(string));
        this.Columns.Add("PriceA", typeof(string));
        this.Columns.Add("SomeOtherFieldA", typeof(string));
    }
}

public class DataTableB: DataTable
{
    public DataTableB()
    {
        this.Columns.Add("DateB", typeof(string));
        this.Columns.Add("PriceB", typeof(string));
        this.Columns.Add("SomeOtherFieldB", typeof(string));
    }
}

我想将 DataTableA.DateA 和 DataTableB.DateB 的值显示在单个列中,并将 DataTableA.PriceA 和 DataTableB.PriceB 的值显示在新 DataGridView 的单个列中。我一直在探索制作一个通用的基类或接口,但还没有多少运气。在不更改列名(不是选项)的情况下,是否可以创建一个能够在同一列中显示两者的绑定?

编辑:
不幸的是,我不认为简单地将 DataTables 合并或聚合到一个新的 DataTable 中会起作用,因为系统的设计使得 DataTableX 类(例如,DataTableA 和 DataTableB)中有逻辑来处理推送数据并更新相应的行数据表。

另外,我不是试图将多个 DataTables 中的 合并到一行中,而是试图在 DataGridView 的一个列中显示具有不同名称的多个列。例如,假设有这样的数据:

数据表A:

日期A 价格A SomeOtherFieldA 20141118 2.0个 20141119 3.0 b

数据表B:

日期B 价格B 其他字段B 20141118 4.0 c 20141119 5.0 天

我想在 DataGridView 中显示以下内容:

日期价格
20141118 2.0
20141119 3.0
20141118 4.0
20141119 5.0

【问题讨论】:

  • 你还可以为聚合表再创建一个类,它将DataTableA和DataTableB作为构造函数的参数,并根据需要将数据放在那里。
  • 您将两个数据表中的数据复制到第三个数据表中。您可以通过处理前两个数据表中的更改事件来保持前两个数据表与第三个数据表同步。
  • @Tarik - 您能否详细说明如何在复制数据后保持数据表同步?
  • 您可以响应 RowChanged、RowDeleted 等 DataTable 事件,并相应地刷新第三个 DataTable。DataTable 事件的完整列表见msdn.microsoft.com/en-us/library/…

标签: c# winforms datagridview datatable


【解决方案1】:

我最终使用了 Tarik 的提示并将目标数据从原始源表复制到目标目标表,然后当源表通过推送数据更新时,我更新目标表中的相应数据。下面是一些示例代码来展示我是如何做到的。

注意: 在我的代码中,我将这个过程称为将数据从源表“反映”到目标表,因为在目标表中只是显示了源表的反映数据,不要与完全无关的对象反射混淆。

复制数据:

首先我制作了字典来将源列名映射到目标表列名。 (目标列名称包含在列表中,因为我需要将单个源列复制到多个目标列 - 如果您不需要这样做,您可以使用简单的字符串字典。)例如:

Dictionary<string, List<string>> reflectedColumnsMapA = new Dictionary<string, List<string>>()
{
    { "DateA", new List<string>() { "Date" }},
    { "PriceA", new List<string>() { "Price" }},
};

Dictionary<string, List<string>> reflectedColumnsMapB = new Dictionary<string, List<string>>()
{
    { "DateB", new List<string>() { "Date" }},
    { "PriceB", new List<string>() { "Price" }},
};

接下来我制作了一个字典,将原始源表行映射到目标表行,用于保持行同步。

Dictionary<DataRow, DataRow> sourceToTargetRowMap = new Dictionary<DataRow, DataRow>();

然后我做了一个方法,将数据从源表复制到目标表,同时填充源到目标行字典。

public void ReflectRowsToTable(DataTable sourceTable, DataTable targetTable, Dictionary<string, List<string>> reflectedColumnsMap)
{
    foreach (DataRow originalRow in sourceTable.Rows)
    {
        DataRow newRow = targetTable.NewRow();

        foreach (KeyValuePair<string, List<string>> keyValue in reflectedColumnsMap)
        {
            foreach (string targetColumn in keyValue.Value)
                newRow[targetColumn] = originalRow[keyValue.Key];
        }

        sourceToTargetRowMap.Add(originalRow, newRow);
        targetTable.Rows.Add(newRow);
    }
}

保持数据同步:

最后,为了保持数据同步,我向所有源表添加了 ColumnChanged 事件处理程序:

sourceTable.ColumnChanged += (s, e) =>
{
    // check if the updated column is one of the columns that were reflected
    if (reflectedColumnsMap.ContainsKey(e.Column.ColumnName))
    {
        // get the target row corresponding to the updated row in the source table
        DataRow reflectedRow = sourceToTargetRowMap[e.Row];
        // update the corresponding columns in the target table
        foreach (string targetColumn in reflectedColumnsMap[e.Column.ColumnName])
        {
            // update the value
            reflectedRow[targetColumn] = e.Row[e.Column.ColumnName];
        }
    }
};

【讨论】:

    猜你喜欢
    • 2017-08-03
    • 2023-03-10
    • 2015-04-25
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-06-12
    • 2013-04-20
    • 1970-01-01
    相关资源
    最近更新 更多