Question

I'm learning Mvvmlight,and quite confused about its canExecute of RelayCommand.

Basically,I have a Button and a PasswordBox in the view,and a Command in the viewModel.What I want is to disable the Button if the PasswordBox is empty.My solution is to pass the PasswordBox as CommandParemeter to the Button,then receive the PasswordBox in the canExecute method and specify if it is null or empty.I first declare a command:

public ICommand CommandClear { get; private set; }

Then instantialize it in the Class Constructor:

CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));

Finally implement the canExecute method as below:

private bool ConfirmCanExecute(object parameter)
{
    bool isExecuable = false;
    var passwordBox = parameter as PasswordBox;
    if (!string.IsNullOrEmpty(passwordBox.Password))
        isExecuable = true;
    return isExecuable;
}

The canExecute method above does not work,as an unhandled exception System.Reflection.TargetInvocationException would be thrown in PresentationFramework.dll.

So I try to wrap the code above with try...catch.This time,it works like magic:

        try
        {
            var passwordBox = parameter as PasswordBox;
            if (!string.IsNullOrEmpty(passwordBox.Password))
                isExecuable = true;
            return isExecuable;
        }
        catch
        {
            return isExecuable;
        }

I'm quite confused about such behavior of canExecute,any ideas?

Était-ce utile?

La solution

Are you declaring p on the stack in this line and does it still exist when the handler is called?

CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));

Because an incorrect command binding would certainly cause this to return null, creating the error you're seeing.

var passwordBox = parameter as PasswordBox;

Secondly, why have your ViewModel directly manipulate the View in this way? Simply 2-way bind the Password field to your ViewModel and your ViewModel's CanExecute handler becomes a one-liner, no?

return !String.IsNullOrEmpty(this.Password);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top