WPF 入门教程 DataGrid数据绑定
介绍
自 .NET 4.0 以来,Microsoft 提供了一个 DataGrid 控件,该控件提供了所需的所有基本功能,例如:
- 自动生成列
- 手动定义列
- 选择
- 分组
- 列排序、重新排序和调整大小
- 行详细信息
- 交替背景画笔
- 冻结列
- 标题可见性
- 如何对自动生成的列进行模板化
基本用法:自动生成列
要显示基本数据网格,只需将
DataGrid
控件拖放到您的视图中并将其绑定
ItemsSource
到数据对象集合即可。DataGrid 提供了一项称为
AutoGenerateColumns
根据数据对象的公共属性自动生成列的功能。它生成以下类型的列:
- 字符串值的文本框列
- 布尔值的复选框列
- 可枚举值的组合框列
- Uri 值的超链接列
<DataGrid ItemsSource="{Binding Customers}" />
推荐一款好用的WPF MVVM框架开源控件库 Newbeecoder.UI

手动定义列
AutoGenerateColumns
或者,您可以通过将属性设置为 来手动定义列
False
。
Columns
在这种情况下,您必须在数据网格的集合中定义列。您可以使用以下类型的列:
-
DataGridCheckBoxColumn
对于布尔值 -
DataGridComboBoxColumn
对于可枚举的值 -
DataGridHyperlinkColumn
对于 Uri 值 -
DataGridTemplateColumn
通过定义您自己的单元格模板来显示任何类型的数据 -
DataGridTextColumn
显示文本值
<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>
选择
数据网格包括多种选择模式。它们由
SelectionMode
and
SelectionUnit
属性配置。
-
SelectionMode
可以设置Single
或Extended
定义是否可以同时选择一个或多个单位。 -
定义了一个选择单元的
SelectionUnit
范围。它可以设置为Cell
,CellAndRowHeader
和FullRow
。
<DataGrid ItemsSource = "{Binding Customers}"
SelectionMode = "Extended" SelectionUnit = "Cell" />
列排序、重新排序和调整大小
数据网格提供了对列进行排序、重新排序和调整大小的功能。它们可以通过以下属性启用或禁用:
-
CanUserReorderColumns
启用或禁用列重新排序 -
CanUserResizeColumns
启用或禁用列大小调整 -
CanUserResizeRows
启用或禁用行大小调整 -
CanUserSortColumns
启用或禁用列排序
<DataGrid ItemsSource = "{Binding Customers}"
CanUserReorderColumns = "True" CanUserResizeColumns = "True" CanUserResizeRows = "False" CanUserSortColumns = "True" />
分组
数据网格还支持分组。要启用分组,您必须定义一个包含至少一个GroupDescription的CollectionView,该GroupDescription定义如何分组的标准。
Customers = new ListCollectionView(_customers);
Customers.GroupDescriptions.Add(new PropertyGroupDescription("Gender"));
您需要做的第二件事是定义组应该是什么样子的模板。你可以将GroupStyle设置为如下代码段。
<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>
行详细信息
数据网格提供了显示所选行的详细信息面板的功能。可以通过将 DataTemplate 设置为
RowDetailsTemplate
属性来启用它。数据模板通过DataContext获取绑定到这一行的对象,并可以绑定到它。
<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>
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}" />
交替背景画笔
您可以定义一个
AlternatingRowBackground
应用于每个偶数行。
AlternationCount
如果您只想对每第 n 个数据行进行墨迹书写,您可以另外指定一个。
<DataGrid ItemsSource = "{Binding Customers}" AlternatingRowBackground = "Gainsboro" AlternationCount = "2" />
冻结列
数据网格还支持冻结列的功能。这意味着当您水平浏览所有列时,它们会保持可见。这是一个有用的功能,可以让引用列(如 ID 或名称)始终可见,以在滚动时保持方向。
要冻结许多列,只需将FrozenColumnCount属性设置为要冻结的列数。
<DataGrid ItemsSource = "{Binding Customers}" FrozenColumnCount = "2" />
标题可见性
您可以通过将
HeadersVisibility
属性设置为
None
、
Row
或
ColumnAll
<DataGrid ItemsSource = "{Binding Customers}" HeadersVisibility = "None" />
如何对自动生成的列进行模板化
如果您想使用 自动生成列
AutoGenerateColumns="True"
,则不能使用
CellTemplates
,因为
DataGrid
自动生成文本、组合、超链接或复选框列,但这些都不是可模板化的。一个简单的解决方法是挂钩自动生成,取消它并始终创建一个
DataGridTemplateColumn
. 以下片段显示了这个想法(代码只是草稿):
public class MyDataGrid : DataGrid
public DataTemplateSelector CellTemplateSelector
get { return (DataTemplateSelector)GetValue(CellTemplateSelectorProperty); }
set { SetValue(CellTemplateSelectorProperty, value); }
public static readonly DependencyProperty CellTemplateSelectorProperty =
DependencyProperty.Register("Selector", typeof(DataTemplateSelector), typeof(MyDataGrid),
new FrameworkPropertyMetadata(null));
protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
e.Cancel = true;
Columns.Add(new DataGridTemplateColumn