You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF MVVM模式下如何获取DataGrid按钮所在行的列值?

在WPF MVVM模式下获取DataGrid行按钮对应的行数据

要在MVVM模式下实现需求,核心是通过命令绑定替代传统的Click事件,并直接传递行数据对象,避免依赖UI元素。以下是具体实现步骤:

1. 修改XAML,绑定命令与行数据

把按钮的Click事件替换为Command绑定,同时将当前行的实体对象作为CommandParameter传递给ViewModel:

<DataGrid Name="NestCards" FontSize="12" 
          ScrollViewer.CanContentScroll="True" MaxHeight="400" ColumnWidth="*"
          ItemsSource="{Binding NestItems}"> <!-- 绑定ViewModel中的数据集合 -->
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Content="Details" 
                            <!-- 绑定到ViewModel中的命令 -->
                            Command="{Binding DataContext.GetDetailsCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
                            <!-- 传递当前行的实体对象 -->
                            CommandParameter="{Binding}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

注:RelativeSource用于定位到DataGrid的DataContext(即ViewModel),确保命令绑定正确。

2. 实现命令基类(若未使用MVVM框架)

如果没有用Prism、MVVM Light等框架,先实现一个简单的RelayCommand用于绑定:

public class RelayCommand<T> : ICommand
{
    private readonly Action<T> _execute;
    private readonly Func<T, bool> _canExecute;

    public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null)
    {
        _execute = execute ?? throw new ArgumentNullException(nameof(execute));
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter) => _canExecute?.Invoke((T)parameter) ?? true;

    public void Execute(object parameter) => _execute((T)parameter);

    public event EventHandler CanExecuteChanged
    {
        add => CommandManager.RequerySuggested += value;
        remove => CommandManager.RequerySuggested -= value;
    }
}

3. 编写ViewModel逻辑

ViewModel需要包含数据集合、命令、UI绑定属性,并实现INotifyPropertyChanged通知UI更新:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;

public class MainViewModel : INotifyPropertyChanged
{
    // DataGrid的数据源,绑定SQL查询结果
    public ObservableCollection<NestItem> NestItems { get; set; } = new ObservableCollection<NestItem>();

    // 处理详情按钮的命令
    public ICommand GetDetailsCommand { get; }

    // 绑定UI显示的属性
    private string _nestStatus;
    public string NestStatus
    {
        get => _nestStatus;
        set
        {
            _nestStatus = value;
            OnPropertyChanged();
        }
    }

    private string _nestName;
    public string NestName
    {
        get => _nestName;
        set
        {
            _nestName = value;
            OnPropertyChanged();
        }
    }

    private string _schedFor;
    public string SchedFor
    {
        get => _schedFor;
        set
        {
            _schedFor = value;
            OnPropertyChanged();
        }
    }

    public MainViewModel()
    {
        GetDetailsCommand = new RelayCommand<NestItem>(ExecuteGetDetails);
        // 这里初始化NestItems,比如从SQL查询加载数据
        // LoadNestItemsFromSql();
    }

    private void ExecuteGetDetails(NestItem selectedItem)
    {
        if (selectedItem == null) return;

        // 直接获取行数据的属性,无需反射
        NestStatus = selectedItem.OrderStatus;
        NestName = selectedItem.NestName;
        SchedFor = selectedItem.DueDate.ToString();

        // 用selectedItem.NestName执行你的SQL查询
        // var details = YourSqlQueryMethod(selectedItem.NestName);
    }

    // 属性变更通知实现
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

4. 定义实体类对应SQL数据

创建与SQL查询结果匹配的实体类,强类型处理数据:

public class NestItem
{
    public string NestName { get; set; }
    public DateTime DueDate { get; set; }
    public string OrderStatus { get; set; }
    // 其他对应SQL字段的属性
}

5. 设置View的DataContext

在窗口或页面的构造函数中,将DataContext绑定到ViewModel:

public MainWindow()
{
    InitializeComponent();
    DataContext = new MainViewModel();
}

核心优势

  • 完全符合MVVM分离原则,UI与业务逻辑解耦
  • 强类型获取行数据,避免反射的低效与不安全
  • 命令绑定更易于测试和维护

内容的提问来源于stack exchange,提问作者user32602103

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 01:03:09