Dhruv Gohil
Dhruv Gohil

Reputation: 842

canExecute(false) not working

I am working on Xamarin Android Application.I don't want to execute Mvxcommand though it is Executing.What is the solution ?
My code is :

 var asd = Mvx.Resolve<MyAddressesViewModel> ();
 asd.ItemSelect.CanExecute (false);

Upvotes: 0

Views: 892

Answers (3)

Trevor Balcom
Trevor Balcom

Reputation: 3888

You are expected to provide a delegate with your MvxCommand that gets called to determine if the user can execute the command. You also are expected to tell Mvvm Cross when to update the CanExecute state manually using RaiseCanExecuteChanged.

Here is an example giving you a Sign In button that is only enabled when there is an EmployeeId filled in by the user, and the user is not currently trying to sign in:

(ViewModel):

    private bool _signInAttemptInProgress;
    protected bool SignInAttemptInProgress
    {
        get { return _signInAttemptInProgress; }
        set
        {
            _signInAttemptInProgress = value; 
            SignInCommand.RaiseCanExecuteChanged();
        }
    }

    private string _employeeId;
    public string EmployeeId
    {
        get { return _employeeId; }
        set
        {
            _employeeId = value; 
            RaisePropertyChanged(() => EmployeeId); 
            SignInCommand.RaiseCanExecuteChanged();
        }
    }

    private MvxCommand _signInCommand;
    public IMvxCommand SignInCommand
    {
        get { return _signInCommand ?? (_signInCommand = new MvxCommand(async () => await OnSignInCommand(), CanExecuteSignInCommand)); }
    }

    private bool CanExecuteSignInCommand()
    {
        return !SignInAttemptInProgress && !string.IsNullOrEmpty(EmployeeId);
    }

    private async Task OnSignInCommand()
    {
        SignInAttemptInProgress = true;
        // Do stuff here. The user can't click the SignIn command inside here.
        SignInAttemptInProgress = false;
        // The user can click the SignIn command again below here.
    }

It would be even cleaner to make your own IMvxCommand implementation that prevents itself from executing again while it's currently executing. Then you don't need to litter your ViewModels with extra SignInAttemptInProgress style properties.

Upvotes: 0

Stephanvs
Stephanvs

Reputation: 731

You can pass in a delegate when creating an instance of your command (probably an MvxCommand within your MyAddressesViewModel.

So probably something like:

class MyAddressesViewModel
{
    public ICommand ItemSelect
    {
        get
        {
            return new MvxCommand(
                () => {}, // Delegate when command gets invoked 
                () => true); // Delegate to determine CanExecute
        }
    }
}

Or something similar.

Also note that as Dhruv mentioned you need to trigger the PropertyChanged event for the command as well using the ChangeCanExecute method to actually call the CanExecute delegate you register in the constructor.

Upvotes: 1

Jauhenka
Jauhenka

Reputation: 162

Invoke the ChangeCanExecute() method.

Upvotes: 0

Related Questions