2016-11-22 74 views
1

我想基於某些條件啓用,禁用和重新啓用我的WPF程序中的某些鍵盤筆劃。我已在當前​​結合這樣的:C#與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> 
... 

然後在視圖模型:

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

現在,這個作品像預想的那樣,除了啓用所有的時間,而在程序運行鍵綁定。遊戲結束後,遊戲區不會消失,但我不希望用戶能夠移動(〜使用鍵),直到他/他通過SetUpGame()開始新遊戲。這就是爲什麼我想將[Up-Down-Left-Right]Command綁定到SetUpGame()而不是構造函數(並將其解除綁定到Model_Gameover)。但是,如果我確實將新DelegateCommands的實例移動到SetUpGame(),那麼鍵綁定不會發生,我無法播放。 Lvl[1-2-3]Command按預期工作,但鍵盤綁定沒有(但它在構造函數中工作)。

如何確保在遊戲結束後鍵盤綁定被啓用,但在Model_GameOver之前被禁用,直到SetUpGame再次運行?爲什麼要將new DelegateCommand s設置爲SetUpGame()不起作用?謝謝!

加成

我已經IPropertyChanged實現如下:

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

這是行不通的。我錯過了什麼?

回答

0

你的命令仍然是綁定的屬性,只有一個特殊的類型ICommand。這意味着它的作用與任何其他綁定相同。如果你想讓元素獲得對綁定屬性的更改,他們需要提升PropertyChanged。因爲您的命令使用自動屬性,所以不會引發該事件。

您不需要的原因通常必須這樣做是在綁定評估之前發生的構造函數中的屬性賦值。

至於「去除」綁定;您可以將它們設置爲空(並根據需要提升PropertyChanged),但更好的解決方案是使用支持CanExecute/CanExecuteChangedDelegateCommand(或自定義命令對象),並使用它來在程序不在有效狀態。

+0

對不起,我沒有準確的描述我自己的問題..水平命令工作正常,鍵盤命令沒有。我已經將「IPropertyChanged」的實現添加到了我已經實現的問題中。 –

+0

哦,等待它的工作,如果我明確地添加'OnPropertyChange(「UpCommand」)等 –

+0

至於刪除的綁定,我試着'DownCommand.CanExecute(false);'和事後'OnPropertyChanged(「DownCommand」 );',但這並不禁用綁定。我錯過了什麼嗎? –