Min*_*amy 5 mvvm windows-phone-7 windows-phone windows-phone-8
我想将MVVM模式实现到注册页面,如下所示:
页面包含用户名,电子邮件和密码的文本框.
我想使用ICommand和DelegateCommand模式将Register Button绑定到命令.
问题是我希望如果文本框为空则禁用该按钮,如果文本框有文本则启用.
我的模型是:
public class User
{
public string UserName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的ViewModel:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
我的代表命令实施:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
和我的观点:
<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>
Run Code Online (Sandbox Code Playgroud)
我想要实现的是使按钮被禁用,直到用户在每个TextBox中输入信息
如何才能做到这一点 ?
谢谢
首先要做的事情是:DelegateCommand每次访问该属性时返回一个新的将限制您调用该RaiseCanExecuteChanged()方法的能力,因为您将没有对绑定的相同命令的引用.
因此,将ViewModel更改为:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
您可以将RegisterCommand属性private set与没有PropertyChanged调用一样的原因,因为它将在绑定发生之前进行实例化,并且不需要更改.
假设属性的形式UserName并Password触发PropertyChanged事件,您可以在更改时调用RaiseCanExecuteChanged()方法RegisterCommand.
例如.
private string _userName;
public string UserName
{
get { return _userName; }
set
{
if(_userName == value)
return;
_userName = value;
RaisePropertyChanged("UserName");
RegisterCommand.RaiseCanExecuteChanged();
}
}
Run Code Online (Sandbox Code Playgroud)
这将强制CanExecute方法重新评估.
| 归档时间: |
|
| 查看次数: |
4150 次 |
| 最近记录: |