WPF DataGrid绑定需用ObservableCollection并实现INotifyPropertyChanged,启用IsReadOnly="False"和CanUserSort="True",Binding设Mode=TwoWay,编辑后通过CellEditEnding事件获取提交值。

WPF DataGrid绑定数据必须用ObservableCollection
直接赋值List或数组会导致新增/删除行不刷新界面,编辑后属性变更也不触发UI更新。根本原因是DataGrid依赖INotifyCollectionChanged和INotifyPropertyChanged通知机制。ObservableCollection实现了前者,而你的数据类必须实现后者(或用INotifyPropertyChanged的简易写法,比如C# 12的record class配合property语法糖)。
常见错误现象:DataGrid显示数据但无法新增行、删行后UI卡在旧状态、双击单元格进不去编辑模式。
- 不要用
new List直接赋给() ItemsSource - 确保实体类每个可编辑字段都是public set属性,并在set中调用
OnPropertyChanged() - 如果用
DataTable,它本身支持编辑和通知,但排序需额外处理(见下文)
DataGrid开启编辑和排序的必要属性设置
默认情况下DataGrid只读且不响应点击表头排序。必须显式启用,否则双击单元格无反应,点列头也没排序图标。
关键配置项:
-
IsReadOnly="False":允许单元格编辑(注意:不影响列级只读) -
CanUserSort="True":启用列头点击排序(默认true,但建议显式写上) -
AutoGenerateColumns="True"或手动定义DataGridTextColumn时,确保Binding有Mode=TwoWay(尤其自定义列) - 如果某列不想被编辑,加
IsReadOnly="True"到对应DataGridColumn
示例XAML片段:
<datagrid itemssource="{Binding People}" isreadonly="False" canusersort="True"><datagrid.columns><datagridtextcolumn header="姓名" binding="{Binding Name, Mode=TwoWay}"></datagridtextcolumn><datagridtextcolumn header="年龄" binding="{Binding Age, Mode=TwoWay}"></datagridtextcolumn></datagrid.columns></datagrid>
排序失效?检查Binding路径和数据类型是否匹配
点了列头没反应或排序结果错乱,大概率是Binding路径写错,或属性类型不支持默认比较器。比如把string年龄绑成int属性却输入了非数字,会静默失败并中断排序链。
常见问题:
- Binding路径大小写不一致(
Name写成name)→ 绑定失败,排序不触发 - 属性是
int?但UI输入空字符串 → 转换异常,DataGrid放弃该列排序 - 自定义类没重写
ToString()或IComparable,对复杂对象排序时行为不可控 - 后台代码中手动调用
ICollectionView.SortDescriptions.Clear()后忘了重加 → 排序状态丢失
调试建议:打开输出窗口,筛选“Binding”关键字,看是否有System.Windows.Data Error提示。
编辑后数据没保存?别漏掉CommitEdit和CellEditEnding
DataGrid编辑是延迟提交的——用户输完按Enter或Tab才真正写回源属性。如果直接取ItemsSource[0].Name,可能还是旧值。更隐蔽的问题是:程序逻辑在用户还没确认编辑时就执行了保存操作。
可靠做法:
- 监听
CellEditEnding事件,在e.EditAction == DataGridEditAction.Commit时处理刚提交的值 - 避免在
BeginningEdit或PreparingCellForEdit里改数据源 - 如需强制提交当前编辑,调用
dataGrid.CommitEdit(DataGridEditingUnit.Row, true),但注意这会跳过验证逻辑 - 如果用了
DataRowView或DataTable,记得调用DataRow.EndEdit(),否则RowState仍是Modified
容易被忽略的是:当用户点击其他行、切换Tab页、甚至Alt+Tab切出窗口时,编辑可能自动提交——这个时机不可控,不能假设“用户一定按Enter”。










