我有一个文本框和一个按钮,它们绑定(bind)到 View 模型中的属性,如下所示
<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 失去焦点。
有解决办法吗?
最佳答案
尝试使用绑定(bind)的 UpdateSourceTrigger
属性。默认情况下,TextBox 将其设置为 LostFocus
事件,因此在本例中,在该事件之后调用 RaiseCanExecuteChanged
。在WPF中,我们可以将其设置为PropertyChanged。通过该设置,RaiseCanExecuteChanged
将在文本属性值更改后立即引发,而无需等待 LostFocus
事件:
<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
遗憾的是,PropertyChanged
在 Windows Phone 版 silverlight 中不可用。我们需要使用 Explicit
并在引发 TextChanged
事件时手动引发绑定(bind) 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/绑定(bind)相关的任务,而不是数据相关的任务。
引用文献:
关于mvvm - Windows Phone 文本框在 TextChanged 上引发命令 RaiseCanExecuteChanged?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21879575/