VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • C#操作DataGrid控件——表格数据展示与编辑

第二部分:桌面应用开发
18. DataGrid控件——表格数据展示与编辑
实例介绍
之前用ItemsControl展示任务列表时,编辑一条任务得点按钮、弹窗口,步骤繁琐;用户反馈“改个截止日期还要点三次,太麻烦”。后来换成DataGrid控件:任务数据直接以表格形式展示,双击单元格就能编辑(比如完成状态点复选框、截止日期用日期选择器),还能一键排序/筛选。用户说“终于像个正经的管理工具了”,效率提升不止一倍。这节就带你给任务管理工具加上DataGrid,彻底解决表格数据的展示与编辑痛点。
需求分析
DataGrid要解决“表格数据高效交互”问题,具体需求如下:
1.数据展示:清晰呈现任务的标题、截止日期、完成状态;
2.直接编辑:单元格双击/回车即可编辑,支持复选vb.net教程C#教程python教程SQL教程access 2010教程
框(完成状态)、日期选择器(截止日期)等专用控件;
3.列自定义:隐藏不必要的列(如ID),自定义列的显示与编辑模板;
4.排序筛选:支持按截止日期排序,筛选完成/未完成任务;
5.编辑验证:截止日期不能早于当前日期,标题不能为空;
6.样式统一:与全局样式(如按钮、输入框)保持一致,表格行 hover 效果自然;
7.性能优化:数据量大时启用虚拟滚动,避免卡顿。
代码实现
前置条件:.NET 6+、WPF;延续任务管理工具案例,复用TaskItem、TaskViewModel及全局样式;需引用System.Windows.Data(排序/筛选)。
场景1:基础DataGrid展示任务
用DataGrid绑定ViewModel的TaskList,自动生成列(快速上手)。
MainWindow.xaml中添加DataGrid
xml

	<Grid Margin="10">
	<!-- 基础DataGrid -->
	<DataGrid x:Name="TaskDataGrid"
	ItemsSource="{Binding TaskList}"
	AutoGenerateColumns="True"
	CanUserAddRows="False"
	Margin="10"
	FontSize="14"
	RowHeight="35"/>
	</Grid>

TaskViewModel中初始化数据
csharp

	public partial class TaskViewModel : ObservableObject
	{
	[ObservableProperty]
	private ObservableCollection<TaskItem> _taskList = new();
	
	public TaskViewModel()
	{
	// 模拟数据
	TaskList.Add(new TaskItem { Title = "学习DataGrid", DueDate = DateTime.Now.AddDays(3), IsCompleted = false });
	TaskList.Add(new TaskItem { Title = "写表格编辑功能", DueDate = DateTime.Now.AddDays(-1), IsCompleted = true });
	TaskList.Add(new TaskItem { Title = "优化样式", DueDate = DateTime.Now.AddDays(5), IsCompleted = false });
	}
	}

场景2:自定义列(复选框+日期选择器)
关闭自动生成列,自定义列类型(完成状态用复选框,截止日期用日期选择器)。
MainWindow.xaml中自定义列
xml

	<DataGrid x:Name="TaskDataGrid"
	ItemsSource="{Binding TaskList}"
	AutoGenerateColumns="False" <!-- 关闭自动生成列 -->
	CanUserAddRows="False"
	Margin="10"
	FontSize="14"
	RowHeight="35"
	CellEditEnding="TaskDataGrid_CellEditEnding"> <!-- 编辑结束事件(验证用) -->
	<DataGrid.Columns>
	<!-- 1. 完成状态列(复选框) -->
	<DataGridCheckBoxColumn Header="完成" 
	Binding="{Binding IsCompleted, Mode=TwoWay}"
	Width="60"
	IsReadOnly="False"/>
	
	<!-- 2. 任务标题列(文本) -->
	<DataGridTextColumn Header="任务标题"
	Binding="{Binding Title, Mode=TwoWay}"
	Width="*"
	IsReadOnly="False"/>
	
	<!-- 3. 截止日期列(日期选择器) -->
	<DataGridTemplateColumn Header="截止日期" Width="150">
	<!-- 显示模板(TextBlock) -->
	<DataGridTemplateColumn.CellTemplate>
	<DataTemplate>
	<TextBlock Text="{Binding DueDate, StringFormat='yyyy-MM-dd'}"
	VerticalAlignment="Center"/>
	</DataTemplate>
	</DataGridTemplateColumn.CellTemplate>
	<!-- 编辑模板(DatePicker) -->
	<DataGridTemplateColumn.CellEditingTemplate>
	<DataTemplate>
	<DatePicker SelectedDate="{Binding DueDate, Mode=TwoWay}"
	VerticalAlignment="Center"/>
	</DataTemplate>
	</DataGridTemplateColumn.CellEditingTemplate>
	</DataGridTemplateColumn>
	</DataGrid.Columns>
	</DataGrid>

场景3:编辑验证(截止日期+标题)
在CellEditEnding事件中验证编辑内容,不符合规则则取消编辑。
MainWindow.xaml.cs中添加验证逻辑
csharp

	private void TaskDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
	{
	var task = e.Row.Item as TaskItem;
	if (task == null) return;
	
	// 1. 验证标题(不能为空)
	if (e.Column.Header.ToString() == "任务标题")
	{
	var textBox = e.EditingElement as TextBox;
	if (string.IsNullOrWhiteSpace(textBox?.Text))
	{
	MessageBox.Show("任务标题不能为空!", "验证失败", MessageBoxButton.OK, MessageBoxImage.Warning);
	e.Cancel = true; // 取消编辑
	return;
	}
	}
	
	// 2. 验证截止日期(不能早于今天)
	if (e.Column.Header.ToString() == "截止日期")
	{
	var datePicker = e.EditingElement as DatePicker;
	if (datePicker?.SelectedDate < DateTime.Today)
	{
	MessageBox.Show("截止日期不能早于今天!", "验证失败", MessageBoxButton.OK, MessageBoxImage.Warning);
	e.Cancel = true; // 取消编辑
	return;
	}
	}
	}

场景4:排序与筛选
用CollectionViewSource实现排序(按截止日期)和筛选(完成/未完成任务)。
MainWindow.xaml中添加排序筛选控件
xml

	<StackPanel Orientation="Horizontal" Margin="10">
	<Button Content="按截止日期排序" Click="SortByDueDate_Click" Margin="0 0 10 0"/>
	<ComboBox x:Name="FilterComboBox"
	Width="150"
	SelectionChanged="FilterComboBox_SelectionChanged">
	<ComboBoxItem Content="全部任务"/>
	<ComboBoxItem Content="已完成任务"/>
	<ComboBoxItem Content="未完成任务"/>
	</ComboBox>
	</StackPanel>

MainWindow.xaml.cs中排序筛选逻辑
csharp

	private ICollectionView _taskView;
	
	public MainWindow()
	{
	InitializeComponent();
	var viewModel = new TaskViewModel();
	DataContext = viewModel;
	// 获取TaskList的视图(用于排序筛选)
	_taskView = CollectionViewSource.GetDefaultView(viewModel.TaskList);
	}
	
	// 按截止日期排序
	private void SortByDueDate_Click(object sender, RoutedEventArgs e)
	{
	_taskView.SortDescriptions.Clear();
	_taskView.SortDescriptions.Add(new SortDescription(nameof(TaskItem.DueDate), ListSortDirection.Ascending));
	}
	
	// 筛选任务
	private void FilterComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
	{
	var selectedItem = FilterComboBox.SelectedItem as ComboBoxItem;
	if (selectedItem == null) return;
	
	switch (selectedItem.Content.ToString())
	{
	case "已完成任务":
	_taskView.Filter = item => (item as TaskItem)?.IsCompleted == true;
	break;
	case "未完成任务":
	_taskView.Filter = item => (item as TaskItem)?.IsCompleted == false;
	break;
	default:
	_taskView.Filter = null; // 显示全部
	break;
	}
	}

场景5:性能优化(虚拟滚动)
数据量大时启用虚拟滚动,只渲染可见行(减少内存占用)。
MainWindow.xaml中开启虚拟滚动
xml

	<DataGrid x:Name="TaskDataGrid"
	ItemsSource="{Binding TaskList}"
	AutoGenerateColumns="False"
	CanUserAddRows="False"
	Margin="10"
	FontSize="14"
	RowHeight="35"
	EnableRowVirtualization="True" <!-- 启用行虚拟滚动 -->
	VirtualizingStackPanel.IsVirtualizing="True"
	VirtualizingStackPanel.VirtualizationMode="Recycling" <!-- 复用行容器(性能更好) -->
	MaxHeight="500"/> <!-- 限制高度,显示滚动条 -->

逐行讲解
场景1:基础DataGrid
ItemsSource:绑定ViewModel的TaskList(ObservableCollection),DataGrid自动同步数据变化;
AutoGenerateColumns:True时自动根据TaskItem的属性生成列(如Title→文本列,IsCompleted→复选框列),False时手动定义列;
CanUserAddRows:False关闭自动添加行(避免用户误加空行);
RowHeight:设置行高(统一样式)。
场景2:自定义列
DataGridCheckBoxColumn:绑定IsCompleted(布尔值),直接显示复选框(无需编辑模板);
DataGridTextColumn:绑定Title(字符串),显示文本;
DataGridTemplateColumn:自定义列(灵活度最高),分CellTemplate(显示模式)和CellEditingTemplate(编辑模式);
CellTemplate:用TextBlock显示格式化的日期(StringFormat='yyyy-MM-dd');
CellEditingTemplate:用DatePicker让用户选择日期(提升编辑体验)。
场景3:编辑验证
CellEditEnding事件:单元格编辑结束前触发(可取消编辑);
e.EditingElement:获取编辑中的控件(如TextBox、DatePicker);
e.Cancel:设置为True取消编辑(保留原内容);
验证逻辑:针对不同列(标题/日期)分别验证,不符合规则则提示并取消。
场景4:排序与筛选
ICollectionView:DataGrid的ItemsSource实际绑定的是视图(而非原始集合),视图支持排序/筛选;
SortDescriptions:添加排序规则(如按DueDate升序);
Filter:设置筛选条件(如只显示已完成任务);
CollectionViewSource:可在XAML中定义视图(更符合MVVM),比如
场景5:虚拟滚动
EnableRowVirtualization:开启行虚拟滚动(只渲染可见行);
VirtualizationMode="Recycling":复用行容器(避免频繁创建/销毁行,提升性能);
MaxHeight:限制DataGrid高度,显示垂直滚动条(触发虚拟滚动)。
基础知识拓展

  1. DataGrid核心列类型
    列类型 用途说明
    DataGridTextColumn 显示/编辑文本(如标题、描述)
    DataGridCheckBoxColumn 显示/编辑布尔值(如完成状态)
    DataGridComboBoxColumn 显示/编辑下拉列表(如任务优先级:高/中/低)
    DataGridTemplateColumn 自定义列(如日期选择器、图片、按钮组合)
    DataGridHyperlinkColumn 显示超链接(如任务链接)
  2. 编辑模式与事件
    编辑触发方式:双击单元格、按Enter键、点击F2键;
    关键事件:
    BeginningEdit:开始编辑前触发(可取消);
    CellEditEnding:编辑结束前触发(验证用);
    RowEditEnding:行编辑结束前触发(整行验证);
    编辑模式:
    Cell:单元格编辑(默认);
    Row:整行编辑(需按Enter确认)。
  3. MVVM友好的排序/筛选
    在ViewModel中用ICollectionView管理视图(避免在View层写逻辑):
    csharp
	public partial class TaskViewModel : ObservableObject
	{
	private readonly ICollectionView _taskView;
	
	[ObservableProperty]
	private ObservableCollection<TaskItem> _taskList = new();
	
	public ICollectionView TaskView => _taskView;
	
	public TaskViewModel()
	{
	_taskView = CollectionViewSource.GetDefaultView(TaskList);
	// 默认排序:按截止日期升序
	_taskView.SortDescriptions.Add(new SortDescription(nameof(TaskItem.DueDate), ListSortDirection.Ascending));
	}
	
	// 筛选命令(按完成状态)
	[RelayCommand]
	private void FilterTasks(bool isCompleted)
	{
	_taskView.Filter = item => (item as TaskItem)?.IsCompleted == isCompleted;
	}
	}
  1. 分页实现
    DataGrid本身不支持分页,需手动实现:
    PagedCollectionView:第三方库(如System.Windows.Data.PagedCollectionView)支持分页;
    自定义分页:用ObservableCollection显示当前页数据,加页码按钮(上一页/下一页/页码选择);
    示例:每页显示10条,计算总页数TotalPages = (int)Math.Ceiling(TaskList.Count / 10.0),当前页数据CurrentPageTasks = TaskList.Skip((CurrentPage-1)*10).Take(10).ToList()。
  2. 样式定制
    全局样式:在App.xaml中定义DataGrid样式(统一外观):
    xml
	<Style TargetType="DataGrid">
	<Setter Property="Background" Value="White"/>
	<Setter Property="BorderBrush" Value="#E0E0E0"/>
	<Setter Property="RowBackground" Value="White"/>
	<Setter Property="AlternatingRowBackground" Value="#F5F5F5"/> <!-- 交替行颜色 -->
	<Setter Property="RowHeaderWidth" Value="0"/> <!-- 隐藏行头 -->
	</Style>

行Hover效果:用DataGridRow的触发器实现:
xml

	<Style TargetType="DataGridRow">
	<Style.Triggers>
	<Trigger Property="IsMouseOver" Value="True">
	<Setter Property="Background" Value="#E3F2FD"/> <!-- 浅蓝色hover -->
	</Trigger>
	</Style.Triggers>
	</Style>

总结
DataGrid是WPF中表格数据交互的核心控件,适合需要高效展示/编辑数据的场景(如任务管理、数据报表)。关键要点:
1.自定义列:用DataGridTemplateColumn实现灵活的列(如日期选择器);
2.编辑验证:用CellEditEnding事件确保数据正确性;
3.排序筛选:通过ICollectionView实现(符合MVVM);
4.性能优化:启用虚拟滚动(数据量大时必备);
5.样式统一:用全局样式定制外观(提升用户体验)。
比如任务管理工具中,DataGrid让用户直接在表格里编辑任务,省去了弹窗和按钮,效率提升明显。掌握这些技巧,你可以轻松实现专业的表格交互功能!

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49467.html



相关教程