如何在DataGrid编辑/新增行时通过CellTemplateSelector切换按钮模板
解决DataGrid编辑/新增模式下通过CellTemplateSelector切换按钮模板的问题
我来帮你搞定这个困扰!核心问题是要在DataGridButtonSelector里识别当前行的编辑/新增状态,我们可以通过遍历视觉树找到对应的DataGridRow,再检查它的状态属性来实现。
完整解决方案代码
首先修改你的DataGridButtonSelector类,添加视觉树查找的辅助方法,并判断行的状态:
class DataGridButtonSelector : DataTemplateSelector { public DataTemplate InsertTemplate { get; set; } public DataTemplate DeleteTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { // 从当前容器向上查找对应的DataGridRow var dataGridRow = FindParent<DataGridRow>(container); // 判断是否处于编辑模式或新增行状态 if (dataGridRow != null && (dataGridRow.IsEditing || dataGridRow.IsNewItem)) { return InsertTemplate; } else { return DeleteTemplate; } } // 辅助方法:递归向上查找指定类型的父元素 private T FindParent<T>(DependencyObject child) where T : DependencyObject { var parentObject = VisualTreeHelper.GetParent(child); if (parentObject == null) return null; if (parentObject is T parent) return parent; else return FindParent<T>(parentObject); } }
然后同步修改XAML里的Selector绑定,直接把模板赋值给Selector的属性(比调用FindResource更可靠):
<Window.Resources> <local:DataGridButtonSelector x:Key="DataGridButtonSelector" InsertTemplate="{StaticResource insertTemplate}" DeleteTemplate="{StaticResource deleteTemplate}" /> </Window.Resources>
关键逻辑说明
- 视觉树查找:
FindParent方法会从传入的container(通常是CellContentPresenter)向上遍历,找到包裹当前单元格的DataGridRow,这是获取行状态的关键。 - 状态判断:
dataGridRow.IsEditing:直接判断当前行是否处于编辑模式dataGridRow.IsNewItem:判断当前行是否是新增的空白行(对应DataGrid的新增模式)
- 模板绑定优化:把模板直接赋值给Selector的依赖属性,避免了资源查找的潜在问题,代码更简洁易维护。
额外注意事项
- 确保你的
DataGrid开启了行编辑功能(默认是支持的,除非手动禁用) - 如果你的新增行有自定义逻辑,
IsNewItem属性会由WPF自动标记,无需额外处理 - 按钮的Visibility绑定可以保留,不影响模板切换逻辑
这样修改后,当用户进入行编辑状态或者添加新行时,按钮会自动切换为“Einfügen”并绑定对应的点击事件;非编辑状态下则显示“Entfernen”,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Hraaig
相关产品推荐
相关产品推荐

