What is CanExecuteChanged for?
Asked Answered
D

3

22

Can I use CanExecuteChanged to change the "can execute" condition?

Or else... "for what" its used?

Deutoplasm answered 25/12, 2010 at 19:24 Comment(0)
B
27

No you can not use it to change the can execute state. It is an event and objects which participate in the ICommand pattern can choose to listen to this event e.g. a button may use this event to know when to re-query the commands state (by calling the can execute method) to set its enabled state.

In order for the can execute pattern to be useful there needs to be something that can be used to raise the event. Prism's DelegateCommand has a method you can call to manually raise this event so subscribers will re-query the can execute method if they have opted into the pattern.

  • Assign command to button.
  • Button subscribes to can execute changed event.
  • Button execute can execute method and it returns false - disables button.
  • You change state that can execute method depends on.
  • You call raise can execute changed on Prism command.
  • Can execute changed event is raised.
  • Button event handler fires.
  • Button calls command can execute method - button is enabled.

Example

In the following Prism based example we change the state of SaveCommand CanExecute from false to true whilst the save command is executing. The call toRaiseCanExecuteChanged will cause the CanExecuteChanged event to be raised, and clients to call the CanExecute method. In practice this would make a Save button that was bound to SaveCommand change its state from enabled to disabled and back to enabled again.

public class BlingViewModel
{
    private DelegateCommand<object> _saveCommand;
    private bool _canSaveExecute = true;

    public ICommand SaveCommand
    {
        get
        {
            if (_saveCommand == null)
            {
                _saveCommand = new DelegateCommand<object>
                    (
                    executeMethod: _ => Save()
                    ,
                    canExecuteMethod: _ => _canSaveExecute
                    );
            }
            return _saveCommand;
        }
    }

    private void Save()
    {
        _canSaveExecute = false;
        _saveCommand.RaiseCanExecuteChanged();

        Console.WriteLine("Saving...");

        _canSaveExecute = true;
        _saveCommand.RaiseCanExecuteChanged();
    }
}
Boson answered 25/12, 2010 at 19:29 Comment(4)
IS there anyway that I can redefine my CanExecute Conditions dynamically ?Deutoplasm
@Anish Yes the idea is for your CanExecute method to refer to some state (e.g. a bool). You can change this at will, but after your change you must call your framework's method of raising the can execute changed event e.g. RaiseCanExecuteChanged for Prism command. All elements that listening to the event will then call the CanExecute method and proceed with the value that is returned.Boson
"You can change this at will," => How can I change it...I need to edit not a new one.Deutoplasm
@Anish you cannot change the can execute method, but you can change the variables which it refers to. I'll try and give you a code sample but I'm on my phone - it's painful!Boson
C
9

Or just call System.Windows.Input.CommandManager.InvalidateRequerySuggested() so that your CanExecute handlers are re-evaluated.

Clarkclarke answered 26/5, 2011 at 16:20 Comment(2)
Good point, thank you. Do you know if this approach has a performance hit (tangible impact, e.g. medium/heavy usage of commands within UI)?Forester
Its not somthing I've had a problem with, I imagine that depends on the number and complexity of the handlers and the performance of the system in general.Clarkclarke
K
2
public override event EventHandler CanExecuteChanged
{    
    add { CommandManager.RequerySuggested += value; }
    remove { CommandManager.RequerySuggested -= value; }
}

I don't know what the performance implications are for this; however, they don't seem to be too great, either way. This is what I use.

Kimberlite answered 29/10, 2015 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.