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"));
}
}