I have a strange data model and I'm trying to generate dynamic columns in a datagrid and bind the items correctly.
I have a list of Row objects that I want to bind to a DataGrid and display using simple DataGridTextColumn.
<controls:DataGrid
Grid.Row="1"
x:Name="dataGrid"
ItemsSource="{x:Bind ViewModel.CurrentRows}"
My objective is to grab a list of columns from the first row and build my grid columns while setting up the bindings. I'm having trouble figuring out the correct way to bind the data at RowValue.value.
public TablePage()
{
InitializeComponent();
dataGrid.ItemsSource = ViewModel.CurrentRows;
foreach (Column column in ViewModel.CurrentRows.FirstOrDefault().Values.Select(x => x.key))
{
dataGrid.Columns.Add(new DataGridTextColumn()
{
Header = column.ColumnValidation.column_label,
Binding = new Binding() { Path = new PropertyPath("Values.value") }
});
}
}
And in my viewmodel I have:
public ObservableCollection<Row> CurrentRows
And a Row object looks like this:
public class Row: INotifyPropertyChanged
{
public List<RowValue> Values { get; set; } = new List<RowValue>();
public event PropertyChangedEventHandler PropertyChanged;
}
And finally a RowValue object looks like this:
public class RowValue: INotifyPropertyChanged
{
public Column key { get; set; }
public string value { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
Column looks like this:
public class Column
{
public string name;
public ColumnValidation ColumnValidation;
}
ColumnValidation looks like this:
public class ColumnValidation
{
public string column_label;
public DataTypeEnum data_type;
public int width;
public int decimal_places;
public int display_order;
public string calculation_formula;
public string edit_style;
public string default_value;
public decimal? minimum_value;
public decimal? maximum_value;
public bool is_column_nullable = false;
public bool inherit_values = false;
public bool display_column = false;
public bool is_editable = false;
public int column_style;
public string code_table_name;
public string code_display_name;
public string code_data_column_name;
}
column_labeland placing it in theRowclass (You need to change the existing data structure). In fact, according to the current binding (ObservableCollection<Row>), you can only display information at the Row level, and the binding pathValues.valuewill not take effect. Becausevalueis an property of theRowValueclass, not a property ofList<RowValue>- Richard Zhang - MSFTDataGridTextColumn, you need to pass in a fixed binding path. If you want to useDataGridTemplateColumn, although it is more customizable, it may not meet your need to automatically generate column names. - Richard Zhang - MSFT