I think you will need to represent your data as hierarchical rows in the DataGrid. You can do that like this.
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding Data}"
RowDetailsVisibilityMode="Visible">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding P1}" />
<DataGridTextColumn Binding="{Binding P2}" />
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding DictionaryInA.Values}"
RowDetailsVisibilityMode="Visible">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid AutoGenerateColumns="False"
ItemsSource="{Binding DictionaryInB.Values}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding P1}" />
<DataGridTextColumn Binding="{Binding P2}" />
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding P1}" />
<DataGridTextColumn Binding="{Binding P2}" />
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Your data will look something like this.
- Class A Row 1
- Class B Row 1
- Class C Row 1
- Class C Row 2
- Class C Row N
- Class B Row 2
- Class C Row 1
- Class C Row 2
- Class C Row N
- Class B Row N
Class C Row 1
Class C Row 2
Class C Row N
- Class A Row 2
- Class B Row 1
- Class C Row 1
- Class C Row 2
- Class C Row N
- Class B Row 2
- Class C Row 1
- Class C Row 2
- Class C Row N
- Class B Row N
Class C Row 1
Class C Row 2
Class C Row N
- Class A Row N
- Class B Row 1
- Class C Row 1
- Class C Row 2
- Class C Row N
- Class B Row 2
- Class C Row 1
- Class C Row 2
- Class C Row N
- Class B Row N
Class C Row 1
Class C Row 2
Class C Row N
If you want expand/collapse functionality, take a look at this link.
Displaying hierarchal parent child data in WPF DataGrid
If you have access to infragistics controls, I would highly recommend using the XamDataGrid instead of the .NET DataGrid. You can pretty much do anything you want with that control.
http://www.infragistics.com/products/wpf/data-grid/
Update
For flat data, you can can create a wrapper for your model like this.
public IEnumerable FlattenedModel
{
get
{
return (from b in TheModel.InstanceOfClassA.DictionaryInA.Values
from c in b.DictionaryInB.Values
select new
{
PropertyA1 = TheModel.PropertyA1,
PropertyA2 = TheModel.PropertyA2,
PropertyB1 = b.PropertyB1,
PropertyB2 = b.PropertyB2,
PropertyC1 = c.PropertyC1,
PropertyC2 = c.PropertyC2
}).ToList();
}
}
If you can't do a wrapper, then a converter will work as well.
public class FlattenTheModelConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var InstanceOfTheModel = value as TheModel;
return (from b in InstanceOfTheModel.InstanceOfClassA.DictionaryInA.Values
from c in b.DictionaryInB.Values
select new
{
PropertyA1 = InstanceOfTheModel .PropertyA1,
PropertyA2 = InstanceOfTheModel .PropertyA2,
PropertyB1 = b.PropertyB1,
PropertyB2 = b.PropertyB2,
PropertyC1 = c.PropertyC1,
PropertyC2 = c.PropertyC2
}).ToList();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
If you decide to use a converter, you will need to modify your XAML as follows.
<DataGrid ItemsSource="{Binding TheModel, Converter={StaticResource FlattenTheModelConverter}, Mode=OneWay}">