2014-11-17 2 views
2

Я унаследовал несколько DataTables с разными именами столбцов, которые все отображаются в их собственных DataGridView. Я хотел бы создать новый дополнительный DataGridView, который отобразит их все в одном DataGridView. Например (очень упрощенной):Отображение строк из нескольких DataTables в одном 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. Я изучал создание общего базового класса или интерфейса, но еще не имел большой удачи. Не изменяя имена столбцов (не вариант), можно ли сделать привязку, которая будет отображаться как в том же столбце?

Edit:
К сожалению, я не думаю, что просто слияние или агрегирование DataTables в новый DataTable будет работать, так как система была разработана таким образом, что есть логика внутри классов DataTableX (например, DataTableA и DataTableB) для обработки push-данных и обновления соответствующей строки в DataTable.

Кроме того, я не пытаюсь объединить строк из нескольких таблиц DataTables в одну строку, я пытаюсь отобразить несколько столбцов с разными именами в одном столбце в 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

использовать этот HTTP: // StackOverflow. com/questions/12278978/combining-n-datatables-in-a-single-datatable –

+0

Также вы можете создать еще один класс для агрегированной таблицы, который будет принимать DataTableA и DataTableB в качестве параметра конструктора и помещать данные там, как вы хотеть. – Gleb

+1

Вы копируете данные из обоих типов данных в третью. Вы можете сохранить первые два данных, синхронизированных с третьими данными, обработкой событий изменений в двух первых таблицах данных. – Tarik

ответ

0

Я закончил использовать подсказку Тарика и скопировал целевые данные из исходных исходных таблиц в целевую таблицу назначения , а затем, когда исходные таблицы обновляются с помощью push-данных, я обновляю соответствующие данные в целевой таблице. Ниже приведен пример кода, чтобы показать, как я это сделал.

Примечание: В моем коде я ссылался на процесс как «отражающий» данные из исходных таблиц в целевую таблицу, так как в целевой таблице просто отображается отражение данных исходных таблиц, а не путать с отражением объекта, которое совершенно не связано.

Копирование данных:

Сначала я сделал словари для сопоставления имен столбцов источника имена столбцов целевой таблицы. (Имена целевого столбца содержатся в списке, потому что мне нужно было скопировать один столбец источника в несколько целевых столбцов - если вам не нужно делать это, вы можете просто использовать простой текстовый словарь.) Например:

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

Keeping данные синхронизированы:

Наконец, чтобы сохранить данные, синхронизированные я добавил обработчики событий 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]; 
     } 
    } 
}; 
Смежные вопросы