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

WPF DataGrid内Button的Command属性绑定错误求助

问题:WPF DataGrid内Button绑定ViewModel中ICommand失败

在WPF的DataGrid中嵌入Button,DataGrid的ItemsSource绑定到实体类集合,希望点击Button时调用ViewModel中的GetSettingsCommand,但运行时出现绑定错误。其他非DataGrid内的Button可正常调用该命令,DataGrid数据显示正常,视图与ViewModel的其他绑定也正常,仅该Button功能失效。

相关代码

XAML代码

<DataGrid Name="gridSettingsData" FontSize="13" BorderThickness="0"  AutoGenerateColumns="False" CanUserAddRows="False" CanUserReorderColumns="False" SelectedItem="{Binding SelectedSettingsStatus, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  ItemsSource="{Binding lstDetailedSettingsStatus, UpdateSourceTrigger=PropertyChanged}" ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"  >
    <DataGrid.Columns>
        <DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=FileType}" ClipboardContentBinding="{x:Null}" Header="FileType" Width="160" />
        <DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=FileStatus}" ClipboardContentBinding="{x:Null}" Header="FileStatus" Width="580" />
        <DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=ExpectedVersion}" ClipboardContentBinding="{x:Null}" Header="ExpectedVersion" Width="120" />
        <DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=LastLoadedVersion}" ClipboardContentBinding="{x:Null}" Header="LastLoadedVersion" Width="120" />

        <DataGridTemplateColumn Header="View" Width="50">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Content="View"
                            Command="{Binding GetSettingsCommand, RelativeSource={RelativeSource AncestorType=viewmodels:vmProgramming}}" 
                            CommandParameter="{Binding ElementName=gridSettingsData, Path=SelectedItem}"  >
                    </Button >
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

    </DataGrid.Columns>
</DataGrid>

ViewModel代码

public class vmProgramming : BaseViewModel, IPageViewModel
{
    public ICommand GetSettingsCommand { get; private set; }

    public vmProgramming()
    {
        // 其他初始化代码...
        GetSettingsCommand = new CommunityToolkit.Mvvm.Input.RelayCommand<object>(GetSettings);
    }

    private async void GetSettings(object obj)
    {
        // 业务逻辑代码,包含异步操作...
    }
}

解决方案

核心问题

DataGrid的CellTemplate内部的数据上下文是当前行的实体类对象,而非ViewModel。原代码中用RelativeSource={RelativeSource AncestorType=viewmodels:vmProgramming}无法找到ViewModel,因为ViewModel是视图的DataContext,不属于可视树的控件类型。

修正步骤

  1. 修改Command绑定,指向视图的DataContext
    选择以下两种方式之一:

    • 方式一:通过RelativeSource查找视图容器
      如果DataGrid所在的视图是Window,修改Button的Command绑定:

      Command="{Binding DataContext.GetSettingsCommand, RelativeSource={RelativeSource AncestorType=Window}}"
      

      若DataGrid在UserControl中,将AncestorType改为UserControl。

    • 方式二:通过ElementName绑定视图
      给视图(Window/UserControl)设置x:Name="root",然后绑定:

      Command="{Binding DataContext.GetSettingsCommand, ElementName=root}"
      
  2. 优化CommandParameter(可选)
    原代码绑定的是DataGrid的选中项,若希望点击当前行Button时直接传递当前行的实体,可简化为:

    CommandParameter="{Binding}"
    

验证

修改后,Button的Command将正确指向ViewModel中的GetSettingsCommand,点击Button会触发GetSettings方法,参数为当前行的实体对象(若使用{Binding})。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:23:25