简体   繁体   中英

C# with WPF - Keyboard not binding?

I want to enable, disable and re-enable certain keyboard strokes in my WPF program based on certain conditions. I have the binding currently like this:

//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>
...

And then in the ViewModel:

//MLViewModel.cs
class MLViewModel : ViewModelBase
{
    public DelegateCommand UpCommand { get; private set; }
    public DelegateCommand DownCommand { get; private set; }
    public DelegateCommand LeftCommand { get; private set; }
    public DelegateCommand RightCommand { get; private set; }

    public MLViewModel(MLModel model)
    {
    ...
        Lvl1Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Easy); });
        Lvl2Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Medium); });
        Lvl3Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Hard); });

        UpCommand = new DelegateCommand(param => { _model.MoveUp(); RefreshTable(); });
        DownCommand = new DelegateCommand(param => { _model.MoveDown(); RefreshTable();});
        LeftCommand = new DelegateCommand(param => { _model.MoveLeft(); RefreshTable(); });
        RightCommand = new DelegateCommand(param => { _model.MoveRight(); RefreshTable(); });    
     }

     private void SetUpGame(MLModel.Level level)
     {
     // setting up the field etc.
     }

    private void Model_GameOver(object sender, MLEventArgs e)
    {
    // handling the event of the game being over
    }
}

Now, this works as supposed, except that the key binding is enabled all the time while the program is running. The gamefield doesn't disappear after a game is finished, but I don't want the user to be able to move (~use the keys) until she/he starts a new game via SetUpGame() . And that's why I'd like to move the [Up-Down-Left-Right]Command binding to SetUpGame() instead of the constructor (and unbind it in Model_Gameover ). However, if I do move the instantiation of the new DelegateCommands to SetUpGame() , the key binding doesn't happen and I'm unable to play. Lvl[1-2-3]Command works as expected, but the keyboard binding doesn't (it does work, however, when it's in the constructor).

How can I make sure the key binding is enabled after SetUpGame until a game is finished, but is disabled after Model_GameOver until SetUpGame is run again? Why is placing the new DelegateCommand s to SetUpGame() not working? Thank you!

ADDITION

I have IPropertyChanged implemented as follows:

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

However, even if I'm trying

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

it doesn't work. What am I missing?

Your commands are still bound properties, just with a special type ICommand . That means that it works the same as any other binding . If you want elements to pick up a change to a bound property they need to raise PropertyChanged . Because your commands are using auto-properties, that event isn't raised.

The reason you don't normally have to do this is property assignments in a constructor happen before the bindings evaluate.

As for "removing" the bindings; you could set them to null (and raise PropertyChanged as appropriate) but a better solution would be to use a DelegateCommand (or a custom command object) that supports CanExecute/CanExecuteChanged and use that to "disable" the commands when the program isn't in a valid state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM