我继承了多个具有不同列名的DataTable,这些列名目前都在他们自己的DataGridViews中显示。我想创建一个新的附加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中的值,并在新DataGridView的单个列中显示DataTableA.PriceA和DataTableB.PriceB中的值。我一直在探索制作一个共同的基类或接口,但还没有太多运气。在不更改列名(不是选项)的情况下,是否可以创建一个能够在同一列中显示的绑定?
修改
不幸的是,我认为简单地将DataTable合并或聚合到一个新的DataTable中是行不通的,因为系统的设计使得DataTableX类中的逻辑(例如,DataTableA和DataTableB)能够处理推送数据并更新相应的行。 DataTable。
另外,我不是试图将多个DataTable中的行合并为一行,我试图在DataGridView的单个列中显示具有不同名称的多个列。例如,假设有这样的数据:
DataTableA:
DateA PriceA SomeOtherFieldA 20141118 2.0 a 20141119 3.0 b
DataTableB:
DateB PriceB SomeOtherFieldB 20141118 4.0 c 20141119 5.0 d
我想在DataGridView中显示以下内容:
Date Price 20141118 2.0 20141119 3.0 20141118 4.0 20141119 5.0
答案 0 :(得分:0)
我最终使用Tarik的提示并将目标数据从原始源表复制到目标目标表,然后当通过推送数据更新源表时,我更新目标表中的相应数据。下面是一些示例代码,用于说明我是如何做到的。
注意:在我的代码中,我将流程称为“反映”源表中的数据到目标表,因为在目标表中只显示了源表的反映数据,不要与对象反射混淆,这是完全不相关的。
复制数据:
首先,我创建了字典,将源列名映射到目标表列名。 (目标列名包含在List中,因为我需要将单个源列复制到多个目标列 - 如果您不需要这样做,则可以使用简单的字符串Dictionary。)例如:
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];
}
}
};