When the columns are automatically generated, they will display the result of the ToString
method for an object, because there is no way of knowing how the display an instance of a custom type.
In case you can manually create your columns, you can specify a property path for already existing column types like DataGridTextColumn
. Suppose that Asset
has a string property called Name
.
<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Reports}">
<DataGrid.Columns>
<DataGridTextColumn Header="Asset" Binding="{Binding Asset.Name}"/>
<!-- ...other columns -->
</DataGrid.Columns>
</DataGrid>
If your data type is more complex, you can instead use a DataGridTemplateColumn
and create custom data templates for displaying and editing.
<DataGridTemplateColumn Header="Asset">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:Report}">
<TextBlock Text="{Binding Asset.Name}"/>
<!-- ...other controls -->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate DataType="{x:Type local:Report}">
<TextBox Text="{Binding Asset.Name}"/>
<!-- ...other controls -->
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
If you absolutely need to auto-generate your columns, you need to hook into the AutoGeneratingColumn
event in code-behind or in a custom behavior.
<DataGrid x:Name="MyDatagrid" ItemsSource="{Binding Reports}">
MyDatagrid.AutoGeneratingColumn += OnAutoGeneratingColumns;
Then change the automatically generated columns or even replace them. In the example below I replaced a column, but you could also just use the e.Column
that is already generated, e.g. a DataGridTextColumn
and set the binding in its Binding
property in code just like in the above example for manually generated columns.
private void OnAutoGeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.Column.Header.Equals("Asset"))
{
// Create a new template column
var templateColumn = new DataGridTemplateColumn
{
Header = e.PropertyName,
// ...set other properties
};
// Create a data template (or get one from a resource dictionary)
var template = new DataTemplate(typeof(Report));
// ...populate the data template and set bindings if needed
// Set the cell template
templateColumn.CellTemplate = template;
// Do the same as above for the editing template if needed
templateColumn.CellEditingTemplate = template;
// Overwrite the auto-generated column
e.Column = templateColumn;
}
// ...handle other columns or leave them as they are
}