2013-01-20 121 views
5

我想要實現MVVM圖案以這樣的registeration頁:的Windows Phone MVVM:按鈕命令可以執行和命令Paramtere

在頁面輸入用戶名,電子郵件地址和密碼文本框。

我要註冊按鈕結合使用ICommand的DelegateCommand模式的命令。

問題是如果文本框是空的,我希望按鈕被禁用,如果它們有文本則啓用。

型號是:

public class User 
    { 
     public string UserName { get; set; } 
     public string Email { get; set; } 
     public string Password { get; set; } 
    } 

視圖模型

public class UserViewModel:INotifyPropertyChanged 
    { 
     private User user; 
     public UserViewModel() 
     { 
      user = new User(); 
     } 
#region Properties 
. 
. 
. 
#endregion 
public ICommand RegisterCommand 
     { 
      get 
      { 
       return new DelegateCommand(Register,CanRegister); 
      } 
     } 

     private void Register(object parameter) 
     { 
      //TODO call the web service 
     } 

     private bool CanRegister(object parameter) 
     { 
      return (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password)); 
     } 
} 

DelegateCommand實現:

public class DelegateCommand:ICommand 
    { 
     //Delegate to the action that the command executes 
     private Action<object> _executeAction; 
     //Delegate to the function that check if the command can be executed or not 
     private Func<object, bool> _canExecute; 

     public bool canExecuteCache; 

     public DelegateCommand(Action<object> executeAction):this(executeAction,null) 
     { 

     } 

     public DelegateCommand(Action<object> action, Func<object, bool> canExecute) 
     { 
      this._executeAction = action; 
      this._canExecute = canExecute; 
     } 

     //interface method, called when CanExecuteChanged event handler is fired 
     public bool CanExecute(object parameter) 
     { 
      //true by default (in case _canExecute is null) 
      bool result = true; 
      Func<object, bool> canExecuteHandler = this._canExecute; 
      if (canExecuteHandler != null) 
      { 
       result = canExecuteHandler(parameter); 
      } 

      return result; 
     } 

     //Event handler that the controld subscribe to 
     public event EventHandler CanExecuteChanged; 


     //interface method 
     public void Execute(object parameter) 
     { 
      _executeAction(parameter); 
     } 


     //rause the CanExecuteChanged event handler manually 
     public void RaiseCanExecuteChanged() 
     { 
      EventHandler handler = this.CanExecuteChanged; 
      if (handler != null) 
      { 
       handler(this, EventArgs.Empty); 
      } 

     } 



    } 

和我查看

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
       <RowDefinition Height="Auto"/> 
      </Grid.RowDefinitions> 
      <TextBlock Grid.Row="0" Text="Username:"/> 
      <TextBox Grid.Row="1" Name="txtUserName" Text="{Binding UserName, Mode=TwoWay}" HorizontalAlignment="Stretch"/> 
      <TextBlock Grid.Row="2" Text="Password:" HorizontalAlignment="Stretch" /> 
      <TextBox Grid.Row="3" Name="txtPassword" Text="{Binding Password, Mode=TwoWay}"/> 
      <Button Grid.Row="4" Content="Register" Command="{Binding RegisterCommand }" /> 
     </Grid> 

我想實現的是使直到用戶禁用該按鈕進入每個文本框

信息如何才能做到這一點?

感謝

回答

7

一兩件事第一:訪問該屬性會限制你調用RaiseCanExecuteChanged()方法,你不會有相同的命令的引用,必將能力的新DelegateCommand每次返回。

因此改變你的視圖模型是這樣的:

public class UserViewModel : INotifyPropertyChanged 
{ 
    private User user; 
    public UserViewModel() 
    { 
     user = new User(); 
     RegisterCommand = new DelegateCommand(Register,CanRegister); 
    } 

    public DelegateCommand RegisterCommand {get; private set;} 

    private void Register(object parameter) 
    { 
     //TODO call the web service 
    } 

    private bool CanRegister(object parameter) 
    { 
     return (!string.IsNullOrEmpty(UserName) && 
       !string.IsNullOrEmpty(Password)); 
    } 
} 

的原因,你可以有RegisterCommand財產private set沒有的PropertyChanged調用,因爲它會被實例化的結合發生,並且不需要前更改。

假設性UserNamePassword觸發PropertyChanged活動的形式,你可以調用RaiseCanExecuteChanged()方法上RegisterCommand,當他們改變。

例如,

private string _userName; 
public string UserName 
{ 
    get { return _userName; } 
    set 
    { 
     if(_userName == value) 
      return; 

     _userName = value; 
     RaisePropertyChanged("UserName"); 

     RegisterCommand.RaiseCanExecuteChanged(); 
    } 
} 

這將強制重新評估CanExecute方法。

+0

非常感謝,你救了我的一天:) –

+0

@MinaSamy我的榮幸:) –