如何在DataGrid指定行启用特定Button?技术实现求助
解决DataGrid中行按钮状态单独控制的问题
你的问题出在DeleteUserButton_OnLoaded方法的逻辑上——你遍历了DataGrid的所有条目,并且反复对当前按钮设置状态,最终所有按钮都会继承最后一个条目的判断结果,自然无法实现每行按钮单独控制的效果。下面给你两种解决方案,先讲快速修复的后台代码方式,再推荐更优雅的MVVM绑定方案。
快速修复:修改后台Loaded事件逻辑
不需要遍历所有DataGrid条目,直接获取当前按钮所在行的TaskUser数据上下文,然后根据这个数据单独判断按钮状态:
private void DeleteUserButton_OnLoaded(object sender, RoutedEventArgs e) { var delete = sender as Button; if (delete == null) return; // 获取当前按钮对应的行数据 var currentTaskUser = delete.DataContext as TaskUser; if (currentTaskUser == null) return; // 根据当前行的UserId判断按钮状态 var isCurrentUser = currentTaskUser.UserId == Identity.This.OnBehalfOfUser.UserId; delete.IsEnabled = isCurrentUser; delete.Visibility = isCurrentUser ? Visibility.Visible : Visibility.Collapsed; }
更优雅的方案:使用MVVM绑定(推荐)
直接在后台处理UI状态不符合WPF的MVVM设计思想,我们可以给TaskUser模型添加一个判断属性,通过绑定来控制按钮状态:
1. 给TaskUser模型添加CanDelete属性
确保模型实现INotifyPropertyChanged接口,这样属性变化时UI会自动更新:
public class TaskUser : INotifyPropertyChanged { // 你的现有属性(UserId、User等)... private bool _canDelete; public bool CanDelete { get => _canDelete; set { _canDelete = value; OnPropertyChanged(nameof(CanDelete)); } } // 实现INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 在ViewModel中初始化CanDelete属性
加载TaskUsers数据时,给每个条目设置是否可删除:
// 假设这是你的ViewModel代码 public ObservableCollection<TaskUser> TaskUsers { get; set; } public YourViewModel() { // 加载你的TaskUsers数据源 TaskUsers = new ObservableCollection<TaskUser>(/*你的数据源*/); // 为每个TaskUser设置CanDelete状态 foreach (var taskUser in TaskUsers) { taskUser.CanDelete = taskUser.UserId == Identity.This.OnBehalfOfUser.UserId; } }
3. 修改XAML绑定按钮状态
首先在窗口/页面资源中添加布尔值转可见性的转换器(如果没有的话):
<Window.Resources> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> </Window.Resources>
然后修改按钮的绑定,去掉后台的Loaded事件:
<Button BorderThickness="0" ToolTip="Delete a User" Click="DeleteTaskUser_OnClick" IsEnabled="{Binding CanDelete}" Visibility="{Binding CanDelete, Converter={StaticResource BooleanToVisibilityConverter}}"> <Image Source="/Sinergi;component/Images/Trash-can-icon16.png" /> </Button>
这样UI状态完全由数据驱动,代码更清晰,也更容易维护。
内容的提问来源于stack exchange,提问作者raihane
相关产品推荐
相关产品推荐

