C#带WPF-键盘未绑定?

C#带WPF-键盘未绑定?,c#,wpf,xaml,C#,Wpf,Xaml,我想在WPF程序中根据特定条件启用、禁用和重新启用某些键盘笔划。我现在有这样的绑定: //MainWindow.xaml ... <Window.InputBindings> <KeyBinding Command="{Binding UpCommand}" Key="Up"/> <KeyBinding Command="{Binding DownCommand}" Key="Down"/> <KeyBinding Command

我想在WPF程序中根据特定条件启用、禁用和重新启用某些键盘笔划。我现在有这样的绑定:

//MainWindow.xaml
...
<Window.InputBindings>
    <KeyBinding Command="{Binding UpCommand}" Key="Up"/>
    <KeyBinding Command="{Binding DownCommand}" Key="Down"/>
    <KeyBinding Command="{Binding LeftCommand}" Key="Left"/>
    <KeyBinding Command="{Binding RightCommand}" Key="Right"/>
</Window.InputBindings>
...
现在,除了在程序运行时一直启用密钥绑定之外,这与假设的一样有效。游戏结束后,游戏场不会消失,但我不希望用户在通过
SetUpGame()
启动新游戏之前能够移动(~使用按键)。这就是为什么我想将
[上下左右]命令
绑定到
SetUpGame()
而不是构造函数(并在
Model\u Gameover
中解除绑定)。但是,如果我将新delegateCommand的实例化移动到
SetUpGame()
,则不会发生键绑定,我无法玩
Lvl[1-2-3]命令
按预期工作,但键盘绑定不工作(但是,当它在构造函数中时,它确实工作)

如何确保在
SetUpGame
游戏结束后启用密钥绑定,但在
Model\u GameOver
游戏结束后禁用密钥绑定,直到再次运行
SetUpGame
?为什么将
new DelegateCommand
s放置到
SetUpGame()
不起作用?谢谢大家!

添加

我已按以下方式实施iPropertyChange:

namespace SavageMaci.ViewModel
{
    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        protected ViewModelBase() { }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
然而,即使我在努力

DownCommand = new DelegateCommand(param => { _model.MoveDown(); RefreshTable(); OnPropertyChanged(); });

它不起作用。我遗漏了什么?

您的命令仍然是绑定属性,只是有一个特殊的类型
ICommand
。这意味着它的工作原理与任何其他绑定相同。如果您希望元素获取对绑定属性的更改,则它们需要引发
PropertyChanged
。因为您的命令正在使用自动属性,所以不会引发该事件

通常不必这样做的原因是构造函数中的属性赋值发生在绑定求值之前


至于“移除”绑定;您可以将它们设置为null(并根据需要提高
PropertyChanged
),但更好的解决方案是使用支持
CanExecute/CanExecuteChanged
DelegateCommand>(或自定义命令对象),并使用它来“禁用”当程序处于无效状态时,这些命令仍然是绑定属性。

您的命令仍然是绑定属性,只是有一个特殊的类型
ICommand
。这意味着它的工作原理与任何其他绑定相同。如果您希望元素获取对绑定属性的更改,则它们需要引发
PropertyChanged
。因为您的命令正在使用自动属性,所以不会引发该事件

通常不必这样做的原因是构造函数中的属性赋值发生在绑定求值之前


至于“移除”绑定;您可以将它们设置为null(并根据需要提高
PropertyChanged
),但更好的解决方案是使用
DelegateCommand
(或自定义命令对象),该对象支持
CanExecute/CanExecuteChanged
,并在程序处于无效状态时使用该对象“禁用”命令。

对不起,我没有准确地描述我自己的问题。。Level命令可以正常工作,而击键命令不能。我已经在问题中添加了
IPropertyChanged
的实现,我已经实现了。哦,等等,如果我显式地添加
OnPropertyChange(“UpCommand”)
等,它确实有效。至于删除绑定,我正在尝试
DownCommand.CanExecute(false)和之后的
OnPropertyChanged(“DownCommand”),但这不会禁用绑定。我错过了什么吗?@lte_uu_u是的,你错过了什么。框架调用
CanExecute
。如果返回值已更改,则命令对象需要引发
CanExecuteChanged
事件。幸运的是,您确切地知道此更改发生的时间,因此如果您调用该事件(很可能通过
RaiseCanceTechChanged
方法),框架将接收它。此时,您无需提出
PropertyChanged
anymore@lte__您可能需要稍微阅读一下WPF命令文档,以确保您完全理解这一切的原因/方式:)对不起,我没有准确地描述我自己的问题。。Level命令可以正常工作,而击键命令不能。我已经在问题中添加了
IPropertyChanged
的实现,我已经实现了。哦,等等,如果我显式地添加
OnPropertyChange(“UpCommand”)
等,它确实有效。至于删除绑定,我正在尝试
DownCommand.CanExecute(false)和之后的
OnPropertyChanged(“DownCommand”),但这不会禁用绑定。我错过了什么吗?@lte_uu_u是的,你错过了什么。框架调用
CanExecute
。如果返回值已更改,则命令对象需要引发
CanExecuteChanged
事件。幸运的是,您确切地知道此更改发生的时间,因此如果您调用该事件(很可能通过
RaiseCanceTechChanged
方法),框架将接收它。此时,您无需提出
PropertyChanged
anymore@lte__您可能需要稍微阅读一下WPF命令文档,以确保您完全理解这一切的工作原理:)
DownCommand = new DelegateCommand(param => { _model.MoveDown(); RefreshTable(); OnPropertyChanged(); });