2013-09-28 37 views
0

下面是一個簡單的屏幕與一個textblock這是「」最初,一個叫button「設置文本」,它設置文本到textblockanother button稱爲「明文」,它總是清除在textblock文本。這就是XAML的外觀。如何更新MVVMLight RelayCommand場景中的UI?

<StackPanel> 
    <TextBlock Text="{Binding DisplayText, Mode=TwoWay}"></TextBlock> 
    <Button Content="Set Text" Command="{Binding SetTextCommand}"></Button> 
    <Button Content="Clear Text" Command="{Binding CancelCommand}" 
           IsEnabled="{Binding CanCancel, Mode=TwoWay}"/> 
</StackPanel> 

這是我的ViewModel代碼。

public class Page1VM : ViewModelBase 
    { 

     public RelayCommand SetTextCommand { get; private set; } 
     public RelayCommand CancelCommand { get; private set; } 

     public Page1VM() 
     { 
      SetTextCommand = new RelayCommand(HandleSetText, CanExecute); 
      CancelCommand = new RelayCommand(HandleClearButtonClick, CanExecuteCancel); 
     } 

     private void HandleSetText(string number) 
     { 
      DisplayText = number; 
     } 

     private string _displayText=""; 
     public string DisplayText 
     { 
      get { return _displayText; } 
      set 
      { 
       _displayText = value; 
       RaisePropertyChanged("DisplayText"); 
       RaisePropertyChanged("CanCancel"); 
      } 
     } 

     private bool _canCancel; 
     public bool CanCancel 
     { 
      get 
      { 
       if (DisplayText == "") 
       { 
        return false; 
       } 
       else 
       { 
        return true; 
       } 
      } 
      set 
      { 
       _canCancel = value; 
       RaisePropertyChanged("CanCancel"); 
      } 
     } 

     private bool CanExecute() 
     { 
      return true; 
     } 
     private bool CanExecuteCancel() 
     { 
      if (DisplayText == "") 
      { 
       return false; 
      } 
      else 
      { 
       return true; 
      } 
     } 
     private void HandleClearButtonClick() 
     { 
      DisplayText = ""; 
     } 
     private void HandleSetText() 
     { 
      DisplayText = "Hello"; 
     } 
    } 

問題:當加載頁面時,「清除文本」按鈕是無效的預計並如預期正常工作。

當我點擊「設置文本」,我通過設置文本值屬性命名DisplayText,也叫RaisePropertyChanged("CanCancel");但即使以後我的「明文」按鈕不會啓用設置文本到文本塊。它背後的原因是什麼?我的文本塊顯示文本值,但「清除文本」按鈕仍未啓用。

+0

你嘗試從命令刪除'CanExecuteCancel'或嘗試調用'RaiseCanExecuteChanged()''上CancelCommand'你改變'DisplayText'?問題是'CanCancel',BTW不需要setter(只讀),不會刷新命令的'CanExecute'。 – dkozl

回答

1

在你的例子中,有一點混淆,就我所知:你基本上不使用'RelayCommand'的內置'CanExecute'機制,但是自己重新構建它,同時仍然定義了CanExecute 'RealyCommand'的方法。 'CanExecute'的想法是自動解除其命令無法執行的控件,因此您不需要手動執行它。在'CanExecute'方法中返回'true'沒有任何意義,因爲您不一定需要在RelayCommand中有一個CanExecute委託(... = new RelayCommand(ExecuteCommand);很好)。您的場景不起作用,因爲您不在'CancelCommand'上調用'RaisCanExecuteChanged()'。

嘗試下面的實現,我刪除了冗餘並插入了缺少的'RaiseCanExecuteChanged()'。查看評論作出解釋:

<StackPanel> 
    <TextBlock Text="{Binding DisplayText, Mode=TwoWay}"></TextBlock> 
    <Button Content="Set Text" Command="{Binding SetTextCommand}"></Button> 
    <Button Content="Clear Text" Command="{Binding CancelCommand}" /> 
</StackPanel> 

,並使用此簡化視圖模型:後

public class Page1VM : ViewModelBase 
{ 
    public RelayCommand SetTextCommand { get; private set; } 

    public RelayCommand CancelCommand { get; private set; } 

    public Page1VM() 
    { 
     SetTextCommand = new RelayCommand(ExecuteSetText); 

     CancelCommand = new RelayCommand(ExecuteCancel, CanExecuteCancel); 
    } 

    private string _displayText=""; 

    public string DisplayText 
    { 
     get { return _displayText; } 
     set 
     { 
      _displayText = value; 
      RaisePropertyChanged("DisplayText"); 
      RaisePropertyChanged("CanCancel"); 
      // Raise the CanExecuteChanged event of CancelCommand 
      // This makes the UI reevaluate the CanExecuteCancel 
      // Set a breakpoint in CanExecuteCancel method to make 
      // sure it is hit when changing the text 
      CancelCommand.RaiseCanExecuteChanged();     
     } 
    } 

    private bool CanExecuteCancel() 
    { 
     // You can simplify the statement like this: 
     return DisplayText != ""; 
    } 

    private void ExecuteCancel() 
    { 
     DisplayText = ""; 
    } 

    private void ExecuteSetText() 
    { 
     DisplayText = "Hello"; 
    } 
}