C# WPF:Canvas上的命令不';行不通

C# WPF:Canvas上的命令不';行不通,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在MVVM中实现一个简单的俄罗斯方块游戏。主面板是画布。我想使用键盘箭头导航。为此,我实现了MoveLeftCommand和MoveRightCommand。这些命令被绑定到ViewModel内部KeyBinding 下面是我的xaml实现 <Canvas Width="{Binding Width}" Height="{Binding Height}" > <Canvas.InputBindings> <!--

我正在
MVVM
中实现一个简单的
俄罗斯方块游戏。主面板是
画布
。我想使用键盘箭头导航。为此,我实现了
MoveLeftCommand
MoveRightCommand
。这些命令被绑定到
ViewModel
内部
KeyBinding

下面是我的
xaml
实现

<Canvas
    Width="{Binding Width}"
    Height="{Binding Height}"
    >
    <Canvas.InputBindings>
        <!-- One type of implementation -->
        <KeyBinding Key="{Binding MoveLeftCommand.GestureKey}"
                    Command="{Binding MoveRightCommand}"/>
        <!-- Different style of implementation -->
        <KeyBinding Key="{Binding MoveLeftCommand.GestureKey}"
                    Command="{Binding MoveLeftCommand}"/>
    </Canvas.InputBindings>
    ...
</Canvas>
下面是命令实现:

public class RelayCommand : ICommand
{
    private Action action;
    public Key GestureKey { get; set; }

    public RelayCommand(Action action) { this.action = action; }

    public bool CanExecute(object parameter) { return true; }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter) { this.action(); }
}        
这个解决方案不起作用

在调试模式下,当我按向左或向右箭头键时,执行甚至不会进入
CanExecute
方法。它的行为就像它不知道命令一样

我还尝试将焦点集中在
画布上。没有结果。
我尝试的另一件事是以不同的方式实现命令。也没有结果

然而,当我在
画布
上添加了一个简单的
文本框
,并在
文本框
上实现了相同的命令后,它就开始工作了——我可以使用箭头导航游戏

你知道为什么
画布上的命令被忽略了吗


谢谢

我认为您的问题来自一个简单的初始化问题

什么都不起作用的原因是绑定发生在RoutedCommand对象创建之前

用以下实现替换命令属性:

    private RelayCommand moveRightCommand;
    public RelayCommand MoveRightCommand
    {
        get
        {
            if (moveRightCommand == null)
            {
                moveRightCommand = new RelayCommand(MoveRight);
                moveRightCommand.GestureKey = Key.Right;
            }
            return moveRightCommand;
        }
    }
或者,您可以按照您的方式创建它们,并在命令的属性上引发PropertyChanged事件

    private RelayCommand moveRightCommand;
    public RelayCommand MoveRightCommand
    {
        get
        {               
            return moveRightCommand;
        }
        set
        {
            moveRightCommand = value;
            PropertyChanged(this, new PropertyChangedEventArgs("MoveRightCommand"));
        }
    }

这是因为
Canvas
没有键盘焦点。WPF从聚焦控件开始,并向上进入视觉树,查看是否有命令处理此手势。例如,将
按钮
放在
画布上
并使其聚焦,然后它应该工作或执行类似于
窗口的操作谢谢,设置焦点效果很好。我以前尝试过强制它,但没有设置
Focusable=True
。至于第一个解决方案,我用一个不同的控件解决了这个问题,但它对我来说有点太粗糙了。命令是在返回指向
GamePanelViewModel
的指针之前在构造函数中创建的,所以它应该可以工作,如果
Canvas
或其中的某个东西具有键盘焦点,它就会工作。我已经尝试了你的两个建议。不幸的是,两者都不起作用。
    private RelayCommand moveRightCommand;
    public RelayCommand MoveRightCommand
    {
        get
        {               
            return moveRightCommand;
        }
        set
        {
            moveRightCommand = value;
            PropertyChanged(this, new PropertyChangedEventArgs("MoveRightCommand"));
        }
    }