Here's the kind of table I am trying to make on xaml:
The user input will always be a string of char, the table will always have 2 rows, the data will always be double. The number of columns changes depending on the length of the string that the user inputs. The user won't be able to edit the table through the interface.
I'm new to WPF and C#, and I hit a very sizeable roadblock here, all help is appreciated
If you need dynamic columns, you should always use a DataTable
as data source. This way you can avoid to build the DataGrid
explicitly in C#/code-behind and instead use the auto-generation feature.
The two helper methods AddColumn
and AddRow
used in the example are candidates to be implemented as extension methods for the DataTable
.
MainWindow.xaml.cs
private void OnSendButtonClick(object sender, EventArgs e)
{
var dataGridSource = new DataTable();
AddColumn<string>(dataGridSource, "type");
foreach (char character in this.TextInput.Text)
{
AddColumn<double>(dataGridSource, character.ToString());
}
// Generate 2 rows of pseudo data
var doubleGenerator = new Random();
for (int rowIndex = 0; rowIndex < 2; rowIndex++)
{
var columnValues = new List<object>();
columnValues.Add(rowIndex < 1 ? "x" : "y");
for (int columnIndex = 0; columnIndex < dataGridSource.Columns.Count; columnIndex++)
{
columnValues.Add(doubleGenerator.NextDouble());
}
AddRow(dataGridSource, columnValues);
}
this.Table.ItemsSource = dataGridSource.DefaultView;
}
private void AddColumn<TData>(DataTable dataTable, string columnName, int columnIndex = -1)
{
DataColumn newColumn = new DataColumn(columnName, typeof(TData));
dataTable.Columns.Add(newColumn);
if (columnIndex > -1)
{
newColumn.SetOrdinal(columnIndex);
}
int newColumnIndex = dataTable.Columns.IndexOf(newColumn);
// Initialize existing rows with default value for the new column
foreach (DataRow row in dataTable.Rows)
{
row[newColumnIndex] = default(TData);
}
}
private void AddRow(DataTable dataTable, IList<object> columnValues)
{
DataRow rowModelWithCurrentColumns = dataTable.NewRow();
dataTable.Rows.Add(rowModelWithCurrentColumns);
for (int columnIndex = 0; columnIndex < dataTable.Columns.Count; columnIndex++)
{
rowModelWithCurrentColumns[columnIndex] = columnValues[columnIndex];
}
}
MainWindow.xaml
<Window>
<StackPanel>
<TextBox x:Name="TextInput" />
<Button Content="Send"
Click="OnSendButtonClick" />
<DataGrid x:Name="Table" />
</StackPanel>
</Window>