Displaying Data in Tables with WPF's DataGrid Control

In Windows Presentation Foundation (WPF) applications, the DataGrid control provides an efficient and flexible way to display data in a tabular format. Whether you're working with data from a database, XML files, or in-memory collections, the DataGrid control simplifies the process of presenting and manipulating data.

Setting up the DataGrid

The first step in using the DataGrid control is to add it to your WPF window or user control. You can do this by dragging and dropping the control from the Toolbox in Visual Studio, or by manually adding the XAML code:

<DataGrid x:Name="myDataGrid" AutoGenerateColumns="True" />

The AutoGenerateColumns Property tells the DataGrid to automatically create columns based on the data source's properties. If you prefer to define the columns manually, you can set AutoGenerateColumns="False" and specify the columns within the DataGrid element.

Binding Data to the DataGrid

Once you have the DataGrid control in place, you can bind it to your data source using the ItemsSource property. The data source can be any implementation of the IEnumerable interface, such as a List<T>, an ObservableCollection<T>, or a data table from a database.

Here's an example of binding the DataGrid to a collection of Person objects:

public partial class MainWindow : Window { private ObservableCollection<Person> people = new ObservableCollection<Person> { new Person { FirstName = "John", LastName = "Doe", Age = 35 }, new Person { FirstName = "Jane", LastName = "Smith", Age = 28 }, new Person { FirstName = "Bob", LastName = "Johnson", Age = 42 } }; public MainWindow() { InitializeComponent(); myDataGrid.ItemsSource = people; } }

In this example, we create an ObservableCollection<Person> and bind it to the ItemsSource property of the DataGrid. The DataGrid will automatically generate columns for each public property of the Person class.

Customizing Columns

While the auto-generated columns are convenient, you may want to customize the appearance and behavior of the columns. You can do this by defining the columns explicitly within the DataGrid element.

<DataGrid x:Name="myDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding People}"> <DataGrid.Columns> <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" Width="120" /> <DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" Width="120" /> <DataGridTemplateColumn Header="Age"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Age}" Foreground="{Binding Age, Converter={StaticResource AgeToColorConverter}}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>

In this example, we define three columns: two DataGridTextColumn instances for the first and last names, and a DataGridTemplateColumn for the age. The DataGridTemplateColumn allows you to define a custom template for displaying the cell content, in this case, using a TextBlock with a custom color converter based on the age value.

Editing Data

The DataGrid control provides built-in support for editing data. By default, users can edit the contents of a cell by double-clicking it or pressing the F2 key. You can enable or disable editing for individual columns using the IsReadOnly property.

<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" Width="120" IsReadOnly="True" />

In this example, the "First Name" column is read-only, while the other columns are editable.

You can also handle the editing events of the DataGrid, such as BeginningEdit, CellEditEnding, and RowEditEnding, to perform custom validation or update operations.

private void myDataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) { // Perform custom validation or initialization logic } private void myDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { // Perform custom validation or update logic }

Styling and Theming

WPF's styling and templating capabilities allow you to customize the appearance of the DataGrid control to match the overall look and feel of your application. You can define styles for the DataGrid itself and individual rows, cells, and column headers.

<Style TargetType="{x:Type DataGridRow}"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" /> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" /> </Trigger> </Style.Triggers> </Style>

In this example, we define a style for DataGridRow elements, setting the background color based on the system colors, and applying a different background and foreground color when the row is selected.


How do I sort the data in the DataGrid?

You can sort the data in the DataGrid by setting the SortMemberPath property of the DataGridColumn or by handling the Sorting event of the DataGrid. For example:

private void myDataGrid_Sorting(object sender, DataGridSortingEventArgs e) { var sortDirection = e.Column.SortDirection == ListSortDirection.Ascending ? ListSortDirection.Descending : ListSortDirection.Ascending; e.Column.SortDirection = sortDirection; e.Handled = true; var dataView = CollectionViewSource.GetDefaultView(myDataGrid.ItemsSource); dataView.SortDescriptions.Clear(); dataView.SortDescriptions.Add(new SortDescription(e.Column.SortMemberPath, sortDirection)); }

How do I filter the data in the DataGrid? 

You can filter the data in the DataGrid by creating a CollectionViewSource and setting its Filter property. For example:

private void FilterData(string filterText) { var dataView = CollectionViewSource.GetDefaultView(myDataGrid.ItemsSource); dataView.Filter = item => { var person = item as Person; return person.FirstName.Contains(filterText) || person.LastName.Contains(filterText); }; }

How do I handle row selection in the DataGrid?

 You can handle row selection in the DataGrid by subscribing to the SelectedCellsChanged event and checking the SelectedItems property. For example:

private void myDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { var selectedItems = myDataGrid.SelectedItems.Cast<Person>().ToList(); // Perform operations on the selected items }

How do I handle cell value changes in the DataGrid? 

You can handle cell value changes in the DataGrid by subscribing to the CellEditEnding event and checking the EditAction property of the event arguments. For example:

private void myDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { if (e.EditAction == DataGridEditAction.Commit) { // Handle the committed cell value change } }

How do I add custom controls or templates to the DataGrid cells?

You can add custom controls or templates to the DataGrid cells by using the DataGridTemplateColumn and defining a custom DataTemplate for the cell content. For example:

<DataGridTemplateColumn Header="Rating"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Rating Value="{Binding Rating}" /> <TextBlock Text="{Binding Rating}" Margin="5,0,0,0" /> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>

In this example, we define a DataGridTemplateColumn that displays a custom Rating control along with a TextBlock showing the numeric value of the rating.

The DataGrid control in WPF provides a powerful and flexible way to display and interact with tabular data in your applications. You can create rich and user-friendly data-driven interfaces tailored to your requirements by leveraging its features and customization options.

Share On