在TextChanged上Windows Phone TextBox引发命令RaiseCanExecuteChanged?

时间:2014-02-19 11:47:42

标签: mvvm windows-phone-8

我有一个文本框和一个按钮,该按钮绑定到我的视图模型中的属性,如下所示

<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失去焦点时,使按钮变为启用状态。

有解决方法吗?

1 个答案:

答案 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 /绑定相关的任务,而不是与数据相关的任务。

参考文献: