Since .NET 4.0, Microsoft is shipping a DataGrid control that provides all the basic functionality needed, like:
To show a basic data grid , just drop a DataGrid
control to your view and bind the ItemsSource
to a collection of data objects and you're done. The DataGrid provides a feature called AutoGenerateColumns
that automatically generates column according to the public properties of your data objects. It generates the following types of columns:
<DataGrid ItemsSource="{Binding Customers}" />
Alternatively you can define your columns manually by setting the AutoGenerateColumns
property to False
. In this case you have to define the columns in the Columns
collection of the data grid. You have the following types of columns available:
DataGridCheckBoxColumn
for boolean values DataGridComboBoxColumn
for enumerable values DataGridHyperlinkColumn
for Uri values DataGridTemplateColumn
to show any types of data by defining your own cell template DataGridTextColumn
to show text values
<DataGrid ItemsSource="{Binding Customers}" AutoGenerateColumns="False" > <DataGrid.Columns> <DataGridTemplateColumn Header="Image" Width="SizeToCells" IsReadOnly="True"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Image Source="{Binding Image}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
The data grid includes a variety of selection modes. They are configured by the SelectionMode
and SelectionUnit
property.
SelectionMode
can be set to Single
or Extended
to define if one or multiple units can be selected simultaneously. SelectionUnit
defines the scope of one selection unit. It can be set to Cell
, CellAndRowHeader
and FullRow
. <DataGrid ItemsSource="{Binding Customers}" SelectionMode="Extended" SelectionUnit="Cell" />
The data grid provides features to sort, reorder and resize columns. They can be enabled or disabled by the following properties:
CanUserReorderColumns
enables or disables column re-ordering CanUserResizeColumns
enables or disables column resizing CanUserResizeRows
enables or disables row resizing CanUserSortColumns
enables or disables column sorting
<DataGrid ItemsSource="{Binding Customers}" CanUserReorderColumns="True" CanUserResizeColumns="True" CanUserResizeRows="False" CanUserSortColumns="True"/>
The data grid also supports grouping. To enable grouping you have to define a CollectionView
that contains to least one GroupDescription
that defines the criterias how to group.
Customers = new ListCollectionView(_customers); Customers.GroupDescriptions.Add(new PropertyGroupDescription("Gender"));
Second thing you need to do is defining a template how the groups should look like. You can do this by setting the GroupStyle
to something like the following snippet.
<DataGrid ItemsSource="{Binding GroupedCustomers}"> <DataGrid.GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Path=Name}" /> </StackPanel> </DataTemplate> </GroupStyle.HeaderTemplate> <GroupStyle.ContainerStyle> <Style TargetType="{x:Type GroupItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type GroupItem}"> <Expander> <Expander.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Name}" /> <TextBlock Text="{Binding Path=ItemCount}"/> <TextBlock Text="Items"/> </StackPanel> </Expander.Header> <ItemsPresenter /> </Expander> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </DataGrid.GroupStyle> </DataGrid>
The data grid provides a feature that shows a detail panel for a selected row. It can be enabled by setting a DataTemplate to the RowDetailsTemplate
property. The data template gets the object that is bound to this row passed by the DataContext and can bind to it.
<DataGrid ItemsSource="{Binding Customers}"> <DataGrid.Columns> <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" /> </DataGrid.Columns> <DataGrid.RowDetailsTemplate> <DataTemplate> <Image Height="100" Source="{Binding Image}" /> </DataTemplate> </DataGrid.RowDetailsTemplate> </DataGrid>
You can specify a RowDetailsTemplateSelector
that selects a data template according to the type or data that this row contains. To do this, create a type that derives from DataTemplateSelector
and override the SelectTemplate
method. In the items
argument you get the data and you can determine which data template to display. Return an instance of that data template as return value.
public class GenderTemplateSelector : DataTemplateSelector { public DataTemplate MaleTemplate { get; set; } public DataTemplate FemaleTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { var customer = item as Customer; if (customer == null) return base.SelectTemplate(item, container); if( customer.Gender == Gender.Male) { return MaleTemplate; } return FemaleTemplate; } }
<l:GenderTemplateSelector x:Key="genderTemplateSelector"> <l:GenderTemplateSelector.MaleTemplate> <DataTemplate> <Grid Background="LightBlue"> <Image Source="{Binding Image}" Width="50" /> </Grid> </DataTemplate> </l:GenderTemplateSelector.MaleTemplate> <l:GenderTemplateSelector.FemaleTemplate> <DataTemplate> <Grid Background="Salmon"> <Image Source="{Binding Image}" Width="50" /> </Grid> </DataTemplate> </l:GenderTemplateSelector.FemaleTemplate> </l:GenderTemplateSelector> <DataGrid ItemsSource="{Binding Customers}" RowDetailsTemplateSelector="{StaticResource genderTemplateSelector}" />
You can define a an AlternatingRowBackground
that is applied every even row. You can additionally specify an AlternationCount
if you only want to ink every every n-th data row.
<DataGrid ItemsSource="{Binding Customers}" AlternatingRowBackground="Gainsboro" AlternationCount="2"/>
The data grid also supports the feature to freeze columns. That means they stay visible while you scoll horizontally through all columns. This is a useful feature to keep a referencing column like an ID or a name always visible to keep your orientation while scrolling.
To freeze a numer of columns just set the FrozenColumnCount
property to the number of columns you want to freeze.
<DataGrid ItemsSource="{Binding Customers}" FrozenColumnCount="2" />
You can control the visibility of row and column headers by setting the HeadersVisibility
property to either None
,Row
,Column
or All
<DataGrid ItemsSource="{Binding Customers}" HeadersVisibility="None" />
From: http://www.wpftutorial.net/DataGrid.html