2013-01-20 100 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我的荣幸:) –