点击EditingCellTemplate内按钮切换DataGrid的CellTemplate与EditingCellTemplate
解决DataGrid单元格模板切换的两种实用方案
你想要的效果是:双击权限单元格进入编辑模式(显示按钮列表),点击按钮更新权限后切回文本显示。我给你两种落地性强的方案,一种基于DataGrid自带的编辑机制,另一种用Behavior封装实现复用,按需选择:
方案一:利用DataGrid自带的CellEditingTemplate(简单直接)
你已经配置好了CellTemplate和CellEditingTemplate,默认双击单元格就会进入编辑状态,核心问题是点击按钮后如何退出编辑。我们可以通过ViewModel触发事件,让View响应并结束单元格编辑:
步骤1:在ViewModel中添加结束编辑的通知事件
public event EventHandler RequestEndEdit; private void ExecuteUpdatePermissionCommand(PermissionLevel selectedPermission) { // 先完成权限更新逻辑 if (SelectedUsersModule != null) { SelectedUsersModule.PermissionLevel = selectedPermission; } // 触发结束编辑的通知 RequestEndEdit?.Invoke(this, EventArgs.Empty); }
步骤2:在View中订阅事件并处理编辑状态
给DataGrid添加Loaded事件,在后台代码中绑定ViewModel的事件:
private void PermissionDataGrid_Loaded(object sender, RoutedEventArgs e) { if (sender is DataGrid dataGrid && dataGrid.DataContext is YourViewModel vm) { vm.RequestEndEdit += (s, args) => { // 提交编辑,让单元格回到CellTemplate状态 dataGrid.CommitEdit(DataGridEditingUnit.Cell, true); // 如果不需要保留编辑临时值,也可以用CancelEdit替代 // dataGrid.CancelEdit(DataGridEditingUnit.Cell); }; } }
步骤3:在XAML中绑定Loaded事件
<DataGrid ItemsSource="{Binding AllUsersModules}" SelectedItem="{Binding SelectedUsersModule}" Style="{StaticResource BaseDataGridStyle}" SelectionUnit="FullRow" Loaded="PermissionDataGrid_Loaded"> <!-- 你的列配置保持不变 --> </DataGrid>
这样点击按钮执行更新命令后,单元格就会自动切回显示模板了。
方案二:用Behavior封装(灵活可复用)
如果你想用Behavior封装这个逻辑,方便在其他DataGrid中复用,可以创建一个附加到DataGridCell的Behavior,手动控制编辑状态:
步骤1:创建PermissionCellEditBehavior
using System.Windows; using System.Windows.Controls; using System.Windows.Interactivity; public class PermissionCellEditBehavior : Behavior<DataGridCell> { // 定义绑定用的IsEditing依赖属性 public static readonly DependencyProperty IsEditingProperty = DependencyProperty.Register(nameof(IsEditing), typeof(bool), typeof(PermissionCellEditBehavior), new PropertyMetadata(false, OnIsEditingChanged)); public bool IsEditing { get => (bool)GetValue(IsEditingProperty); set => SetValue(IsEditingProperty, value); } private static void OnIsEditingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var behavior = d as PermissionCellEditBehavior; if (behavior?.AssociatedObject == null) return; if ((bool)e.NewValue) { // 进入编辑状态 behavior.AssociatedObject.Focus(); behavior.AssociatedObject.IsEditing = true; } else { // 退出编辑并提交 behavior.AssociatedObject.IsEditing = false; behavior.AssociatedObject.CommitEdit(); } } protected override void OnAttached() { base.OnAttached(); // 绑定双击事件触发编辑 AssociatedObject.MouseDoubleClick += OnCellDoubleClick; } protected override void OnDetaching() { base.OnDetaching(); AssociatedObject.MouseDoubleClick -= OnCellDoubleClick; } private void OnCellDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e) { IsEditing = true; } }
步骤2:在ViewModel中添加控制编辑的属性
private bool _isPermissionEditing; public bool IsPermissionEditing { get => _isPermissionEditing; set => SetProperty(ref _isPermissionEditing, value); // 假设你已实现INotifyPropertyChanged } private void ExecuteUpdatePermissionCommand(PermissionLevel selectedPermission) { // 更新权限 SelectedUsersModule.PermissionLevel = selectedPermission; // 结束编辑 IsPermissionEditing = false; }
步骤3:在XAML中附加Behavior
首先添加Interactivity命名空间:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
然后修改权限列的CellStyle:
<DataGridTemplateColumn Header="Permission Level" HeaderStyle="{StaticResource DataGridColumnHeaderStyle}" Width="*" CellTemplate="{StaticResource PermissionTemplate}" CellEditingTemplate="{StaticResource EditingPermissionTemplate}"> <DataGridTemplateColumn.CellStyle> <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}"> <!-- 绑定ViewModel的IsPermissionEditing属性 --> <Setter Property="local:PermissionCellEditBehavior.IsEditing" Value="{Binding DataContext.IsPermissionEditing, RelativeSource={RelativeSource AncestorType=DataGrid}, Mode=TwoWay}"/> <i:Interaction.Behaviors> <local:PermissionCellEditBehavior/> </i:Interaction.Behaviors> </Style> </DataGridTemplateColumn.CellStyle> </DataGridTemplateColumn>
这样双击单元格时Behavior会触发编辑,点击按钮后ViewModel更新IsPermissionEditing为false,Behavior就会让单元格退出编辑状态。
额外提示
如果不想依赖DataGrid的编辑机制,还可以用DataTemplateSelector结合每个数据项的IsEditing属性,完全自定义模板切换逻辑。这种方式更灵活,但需要给每个数据项添加编辑状态属性,适合复杂场景。
内容的提问来源于stack exchange,提问作者Craig Martin
相关产品推荐
相关产品推荐

