I need to be able to support a XamDataGrid which at design time will not have a set number of columns. For example, the app will run, get some data from the server and create some objects. Depending on the response from the server, I may have a different number of objects each time I run the app.
Here is an example of what I mean. Lets say I make a call to some service and get back an xml response with some info. I deserialize that response into a number of objects, which can be different each time the call is made.
Lets say each object has two properties, Label and Value. I would like the grid to show columns with labels that match the value of Label with values from Value. So if I have a two objects, obj1 and obj2, that look like this:
obj1.Label = "Parts"
obj1.Value = "17"
obj2.Label = "Parts"
obj2.Value = "12"
I would like a grid that looks like this, with two rows:
Parts
17
12
If I bind my data source to the grid, the grid automatically just uses the object's properties to create the columns, so I see columns of Label and Value:
Label Value
Parts 17
Parts 12
I am assuming that I cannot achieve what I want just via xaml. Does anyone have an example of what I am looking for? Is it just up to me to create all of the columns during runtime programatically?
<Grid>
<DataGrid Name="dgTest" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=ItemsSource[0].Label}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Value}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
and code:
public partial class Window12 : Window
{
public Window12()
{
InitializeComponent();
List<MyClass> l = new List<MyClass>();
l.Add(new MyClass
{
Label = "Parts",
Value = "17"
});
l.Add(new MyClass
{
Label = "Parts",
Value = "12"
});
dgTest.ItemsSource = l;
}
}
public class MyClass
{
public string Label { get; set; }
public string Value { get; set; }
}