I tried to implement your problem as follows.
The columns define a certain amount of data. But these are few, and we want them to define a repeating column in a DataGrid .
Assume that at least approximately the number of columns and rows is known. Then set the cube values ββin the DataGrid . Below is my example with my comments.
XAML
<Window x:Class="DataGridDynamicAddCol.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen" ContentRendered="Window_ContentRendered"> <Grid> <DataGrid Name="DynamicColumnDataGrid" Loaded="DynamicColumnDataGrid_Loaded" AutoGenerateColumns="False"/> </Grid> </Window>
Code behind
public partial class MainWindow : Window { // Create class with data // Note: Each parameter contains a list of values for it. public class Person { public Person() { FirstName = new List<string>(); SecondName = new List<string>(); Sample = new List<string>(); } public List<string> FirstName { get; set; } public List<string> SecondName { get; set; } public List<string> Sample { get; set; } } // Number of columns const Int32 COLS = 3; // Number of rows const Int32 ROWS = 3; // Number repeats const Int32 RPTS = 3; // Array of headers string[] HeadersArray = new string[COLS] { "FirstName", "SecondName", "Sample" }; // Array of values: Depends on the number of columns and rows // Note: The number of repetitions you can specify smaller amounts of data // If you specify more, then this place will be empty cells string[, ,] ValuesArray = new string[, ,] { { { "Andy", "Caufmann", "Artist"}, { "Sam", "Fisher", "Spy"}, { "Ben", "Affleck", "Actor"} }, { { "Jim", "Gordon", "Sniper"}, { "Maria", "Gray", "Cleaner"}, { "Katy", "Parry", "Artist"} }, { { "Jack", "Rider", "Hunter"}, { "Sven", "Vath", "DJ"}, { "Paul", "Kalkbrenner", "Super DJ"} } }; private List<Person> OnePerson; public MainWindow() { InitializeComponent(); } private void Window_ContentRendered(object sender, EventArgs e) { OnePerson = new List<Person>(); // Create the columns for (int cols = 0; cols < COLS; cols++) { OnePerson.Add(new Person()); } // Create the rows for (int cols = 0; cols < COLS; cols++) { for (int rows = 0; rows < ROWS; rows++) { OnePerson[rows].FirstName.Add(ValuesArray[cols, rows, 0]); OnePerson[rows].SecondName.Add(ValuesArray[cols, rows, 1]); OnePerson[rows].Sample.Add(ValuesArray[cols, rows, 2]); } } DynamicColumnDataGrid.ItemsSource = OnePerson; } private void DynamicColumnDataGrid_Loaded(object sender, RoutedEventArgs e) { // Create dynamically the columns and rows for (int rpts = 0; rpts < RPTS; rpts++ ) { for (int cols = 0; cols < COLS; cols++) { DataGridTextColumn MyTextColumn = new DataGridTextColumn(); MyTextColumn.Header = HeadersArray[cols]; // Binding values from HeadersArray MyTextColumn.Binding = new Binding(String.Format("{0}[{1}]", new object[] { HeadersArray[cols], rpts } )); // Add column in DataGrid DynamicColumnDataGrid.Columns.Add(MyTextColumn); } } } }
Output
The number of repetitions - 3 :

The number of repetitions - 2 :

If you specify how many repetitions there are more than in the cube, you will see the image:

This is quite logical, since the corresponding data is not available.
Note : To use Binding a ViewModel , you need to define the appropriate lists / collection, set them into elements and collect them into one data cube. In my example, static data, but you need to determine the data source, the amount of data, then set it aside and put it in the data cube. I think that without a data cube it will be difficult to implement something like this (I tried different options, using Converter , Binding directly from an array, etc.).