WPF 按钮命令未在 ViewModel 中触发 ICommand

WPF Button Command not firing ICommand in ViewModel

我有一个带有按钮的视图,如下所示:

<Button Grid.Column="2" Grid.Row="1" Content="Test" Margin="10,4" 
        Command="{Binding DataContext.CmdTestButtonClicked}" 
        CommandParameter="{Binding}" />

在视图的代码隐藏中,我将 DataContext 设置为 ViewModel:

public GlobalSettings()
{
    InitializeComponent();

    ...

    DataContext = Helpers.IoCHelper.GlobalSettingsVM;

    ...
}

我的 ViewModel 派生自基础 class,它暴露了 ICommand:

public class GlobalSettingsVM : CollectionViewModel<GlobalSettings> { ... }

public abstract class CollectionViewModel<TModel> : IInstallModuleViewModel, INotifyPropertyChanged,
        INotifyDataErrorInfo where TModel : Model, new()
{
    ...

    public ICommand CmdTestButtonClicked
    {
        get
        {
            return _testButtonClicked ??
                   (_testButtonClicked = new RelayCommand(TestButtonClicked));
        }
    }

    protected virtual void TestButtonClicked(object o)
    {
        // I never get here
    }
}

我在整个应用程序中使用此模式没有任何其他问题,但是我的所有其他实现在 ListView 中都有 Button,因此我必须使用 RelativeSource={RelativeSource AncestorType={x:Type ListView}}.

为什么这个命令永远不会触发?我也需要在这里设置一个RelativeSource吗?

这个

Command="{Binding DataContext.CmdTestButtonClicked}" 

暗示该命令将在按钮绑定到的对象中查找名为 DataContext 的 属性。 如果按钮的 DataContext 是 GlobalSettingsVM 这应该有效:

Command="{Binding CmdTestButtonClicked}" 

您也可以使用 MVVM Light 工具包,它非常方便,可以帮助解决这些情况。

你会得到这样的东西:

<Button Grid.Column="2" Grid.Row="1" Content="Test" Margin="10,4" 
     <i:Interaction.Triggers>
           <i:EventTrigger EventName="OnClick" >
                 <Command:EventToCommand Command="{Binding DataContext.CmdTestButtonClicked}" CommandParameter="{Binding}" PassEventArgsToCommand="True"/>
            </i:EventTrigger>
      </i:Interaction.Triggers>

在我的例子中,我正在 xaml.cs class 的构造函数下收听 PreviewMouseLeftButtonDown 正在停止 command event callbackview model.

 this.PreviewMouseLeftButtonDown += (s, e) => DragMove();

在 xaml 文件中为 window 添加了 MouseLeftButtonDown="Window_MouseLeftButtonDown" 单击处理程序并处理 window 在其中拖动,而不是上面的行,如下所示

private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    DragMove();
}