WPF:Canvas上的命令不起作用

时间:2014-06-14 17:50:53

标签: c# wpf mvvm

我正在Tetris中实施一个简单的MVVM游戏。主面板为Canvas。我想使用键盘箭头导航。为此,我实施了MoveLeftCommandMoveRightCommand。这些命令绑定到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>

命令在ViewModel的构造函数中初始化。

public RelayCommand MoveRightCommand { get; set; }
public RelayCommand MoveLeftCommand { get; set; }

public GamePanelViewModel()
{
    this.MoveLeftCommand = new RelayCommand(new Action(MoveLeft));
    this.MoveLeftCommand.GestureKey = Key.Left;
    this.MoveRightCommand = new RelayCommand(new Action(MoveRight));
    this.MoveRightCommand.GestureKey = Key.Right;
}

这是命令实现:

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方法。它表现得好像没有意识到命令。

我也尝试过强调Canvas。没有结果。 我尝试的另一件事是以不同的方式实现命令。也没有结果。

但是,当我在Textbox之上添加了一个简单的Canvas,并在Textbox上实现了相同的命令后,它就开始工作了 - 我可以使用箭头

知道为什么Canvas上的命令被忽略了吗?

由于

1 个答案:

答案 0 :(得分:0)

我认为您的问题源于一个简单的初始化问题。

无效的原因是因为绑定发生在创建RoutedCommand对象之前。

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

    private RelayCommand moveRightCommand;
    public RelayCommand MoveRightCommand
    {
        get
        {
            if (moveRightCommand == null)
            {
                moveRightCommand = new RelayCommand(MoveRight);
                moveRightCommand.GestureKey = Key.Right;
            }
            return moveRightCommand;
        }
    }

或者,您可以按照自己的方式创建它们,并在Command的属性上引发 PropertyChanged 事件。

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