views:

302

answers:

2

How can I disable a button until required data is entered in a TextBox?

I'm binding an Button to ICommand

        public ICommand LoginCommand
    {
        get
        {
            if (_loginCommand == null)
            {
                _loginCommand = new DelegateCommand<string>(this.Login, this.IsValid);
            }
            return _loginCommand;
        }
    }

in XAML like this:

<Button Style="{StaticResource LoginButton}" Content="Login" Command="{Binding LoginCommand}" CommandParameter="{Binding Text, ElementName=txtUserName}" />
+1  A: 

Where is DelegateCommand defined? Check the constructor, it is probably expecting the second parameter to be a predicate, the result of which gets mapped to your ICommand's CanExecute.

I assume that this.IsValid is a delegate method that returns true if the string.Length > 0 for the Command parameter you are passing from the View... Try setting it to always return false just to check the UI is disabling the button.

EDIT: To get the param into the IsValid method, use the following syntax:

change the syntax of the IsValid method to accept a string parameter, then decalre your DelegateCommand like:

_loginCommand = new DelegateCommand<string>(this.Login, (param) => this.IsValid(param));

HTH :)

IanR
If this.IsValid() method return false UI is disabling the button. That means Button gets disabled as soon the UI loads, since there is no content in the Textbox. My question is how to enable button if text that can be validated as true entered to TextBox?
Raj
DelegateCommand is from the Composite WPF aka Prism library: Microsoft.Practices.Composite.Presentation.Commands
Raj
You need to pass the CommandParameter through to the method... Will update answer to show you how.
IanR
With my current code IsValid method is getting command parameter. The problem I face is that though the text change, Command is not checked again for CanExecute.
Raj
I think issue is related to John Smith's entry over here: http://joshsmithonwpf.wordpress.com/2008/06/17/allowing-commandmanager-to-query-your-icommand-objects/
Raj
A: 

You just need to raise the requery event. This is easy with a DelegateCommand. Here's how your ViewModel would look.

Also, if there's not a compelling reason to make your property of type DelegateCommand, then you should do so.

public class MyViewModel : ViewModel
{

    private string _myTextField;
    public string MyTextField
    {
        get { return _myTextField; }
        set
        {

            _myTextField = value;
            OnPropertyChanged("MyTextField");

            //Here's the magic
            LoginCommand.RaiseCanExecuteChanged();

        }
    }

    public DelegateCommand<string> LoginCommand { get; set; }

    public MyViewModel()
    {
         LoginCommand = new DelegateCommand<string>(Login, CanLogin);
    }

    public bool CanLogin(string text)
    {
         return !string.IsNullOrEmpty(text);
    }

    public void Login(string text)
    {
         //login logic
    }

}

That's pretty much it.

Anderson Imes