2

I have a text box and a button that's bound to a property in my view model as follows

<TextBox  Text="{Binding UserName, Mode=TwoWay}"  />

<Button  Content="Log In"  Command="{Binding LoginCommand}"/>

My UserName property:

private string userName;
        public string UserName
        {
            get
            {
                return this.userName;
            }
            set
            {
                SetProperty(ref userName, value);
                ((DelegateCommand)(this.LoginCommand)).RaiseCanExecuteChanged();
            }
        }

The login command:

LoginCommand = new DelegateCommand(User_Login, Can_Login);

and the Can_Login method:

private bool Can_Login(object arg)
        {
            if (!string.IsNullOrEmpty(UserName))
                return true;
            return false;
        }

My problem is that login button is always enabled untill the user name text box is not empty and has lost focus.

What I want to do is to make the button become enabled once the user types some text in the TextBox instantly without having the TextBox to lose focus.

is there a workaround for this ?

har07
  • 88,338
  • 12
  • 84
  • 137
Mina Wissa
  • 10,923
  • 13
  • 90
  • 158

1 Answers1

4

Try to play with UpdateSourceTrigger property of binding. TextBox has it set to LostFocus event by default, hence RaiseCanExecuteChanged was called after that event in this case. In WPF, we can set it to PropertyChanged. With that setting RaiseCanExecuteChanged will be raised immediately after text property value changed, without waiting for LostFocus event :

<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Unfortunately, PropertyChanged isn't available in silverlight for windows phone. We need to use Explicit and raise binding UpdateSource event manually upon TextChanged event raised :

<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();
}

Note that code-behind in this case is fine (from MVVM pont-of-view), because it is just doing some UI/binding related tasks, not data related tasks.

References :

Community
  • 1
  • 1
har07
  • 88,338
  • 12
  • 84
  • 137
  • 1
    Thanks a lot, it worked for me, maybe wrapping this functionality in a custom control will make it easier – Mina Wissa Feb 20 '14 at 10:15