我有一个文本框和一个按钮,该按钮绑定到我的视图模型中的属性,如下所示
<TextBox Text="{Binding UserName, Mode=TwoWay}" />
<Button Content="Log In" Command="{Binding LoginCommand}"/>
我的用户名属性:
private string userName;
public string UserName
{
get
{
return this.userName;
}
set
{
SetProperty(ref userName, value);
((DelegateCommand)(this.LoginCommand)).RaiseCanExecuteChanged();
}
}
登录命令:
LoginCommand = new DelegateCommand(User_Login, Can_Login);
和 Can_Login 方法:
private bool Can_Login(object arg)
{
if (!string.IsNullOrEmpty(UserName))
return true;
return false;
}
我的问题是登录按钮始终处于启用状态,直到用户名文本框不为空且失去焦点。
我想要做的是在用户立即在TextBox中输入一些文本而不让TextBox失去焦点时,使按钮变为启用状态。
有解决方法吗?
答案 0 :(得分:4)
尝试使用绑定的UpdateSourceTrigger
属性。默认情况下,TextBox将其设置为LostFocus
事件,因此在此情况下,在此事件之后调用RaiseCanExecuteChanged
。在WPF中,我们可以将其设置为PropertyChanged
。使用该设置RaiseCanExecuteChanged
将在文本属性值更改后立即引发,而不等待LostFocus
事件:
<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
不幸的是,PropertyChanged
在Windows Phone的Silverlight中不可用。我们需要使用Explicit
并在TextChanged
事件引发时手动引发绑定UpdateSource事件:
<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
TextChanged="OnTextChanged"/>
//in code-behind
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
BindingExpression bindingExpr = textBox.GetBindingExpression(TextBox.TextProperty);
//Manually call UpdateSource
bindingExpr.UpdateSource();
}
请注意,在这种情况下,代码隐藏很好(来自MVVM pont-of-view),因为它只是执行一些与UI /绑定相关的任务,而不是与数据相关的任务。
参考文献: