Reputation:
Am I missing something in my Command-ViewModel?
public class Command : ICommand
{
public Command(Action execute, Func<bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute ?? new Func<bool>(() => true);
}
private Action execute;
private Func<bool> canExecute;
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return canExecute.Invoke();
}
public void Execute(object parameter)
{
execute?.Invoke();
}
}
Everytime I want to use CanExecuteChanged
in my MainViewModel
with this line of code ((Command)MyCommand).CanExecuteChanged();
it gives me this error The event 'Command.CanExecuteChanged' can only appear on the left hand side of += or -=
Upvotes: 2
Views: 1438
Reputation: 57
Just a another approach!
public sealed class Command : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public RelayCommand(Predicate<object> CanExecute, Action<object> Execute)
{
_canExecute = CanExecute;
_execute = Execute;
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
Then just let the Command Manager handle updating your .CanExecuteChanged
problem :)
If you need to force the Command Manager to "look again" call CommandManager.InvalidateRequerySuggested();
Here is a little more info on the Command Manager How does CommandManager.RequerySuggested work?
Upvotes: 0
Reputation:
I deleted my Command-Class
and now I am using the Xamarin.Forms Command Class
which is making this a lot easier because now I can just use this delicious short line of code: ((Command)MyCommand).ChangeCanExecute();
to fire the event.
Thanks to all of you guys.
Upvotes: 0
Reputation: 292
public event EventHandler CanExecuteChanged;
is syntactic sugar. What the compiler actually generates when you put this in is something like*
private EventHandler _CanExecuteChanged;
public event EventHandler CanExecuteChanged
{
add { _CanExecuteChanged += value; }
remove { _CanExecuteChanged -= value; }
}
So the CanExecuteChange
that's publicly exposed isn't the actual field but only something you can add and remove handlers with.
Related note: The backing field being private
is also the reason for the normal pattern of having a protected
OnXXXX() method in the base class.
public event EventHandler CanExecuteChanged;
protected void OnCanExecuteChanged(EventArgs args)
{
CanExecuteChanged?.Invoke(this, args);
}
*Note the "like" part; there's some null checking that's needed for proper add and remove as well.
Upvotes: 1
Reputation: 3751
To answer your question yes you are missing something from your code. I can't tell if you are using the Command
class supplied by Xamarin.Forms
but if you aren't then you really should be!
Ultimately you cannot interact with an event
outside of the class that it belongs to apart from subscribing for the event notification which is what the 'The event 'Command.CanExecuteChanged' can only appear on the left hand side of += or -=' is telling you. To subscribe you implement something like the following:
MyCommand.CanExecuteChanged += (sender, e) =>
{
// Your code to react to the event goes here.
};
What you can do though and this is where you need to be using the Xamarin.Forms
Command
class (or you can implement something similar yourself in your Command
class). Is call ChangeCanExecute
e.g.
((Command)MyCommand).ChangeCanExecute();
This will then trigger the event to be fired and thus updating any UI controls that are bound to that command.
Upvotes: 0
Reputation: 34083
CanExecuteChanged
is an event. You can only use it like this:
YourCommand.CanExecuteChanged += (sender, args) =>
{
// Do your magic here
};
Upvotes: 4