I need to create an RoutedCommand in my custome control. I had used RoutedCommands in wpf but in uwp there is no RoutedCommand class. Whats the replacement for this?
[Edit] It seems that the whole CommandBinding which is supported by the RoutedCommand is gone in uwp! Since there also exists no IInputElement which was implemented by the FrameworkElement
https://msdn.microsoft.com/en-us/library/ms752070(v=vs.100).aspx
The answer might be a RelayCommand, which also implements ICommand
public class RelayCommand : ICommand
{
private Action _handler;
public RelayCommand(Action handler)
{
_handler = handler;
}
public RelayCommand(Action handler, Func<bool> p) : this(handler)
{
this.p = p;
}
private bool _isEnabled;
private Func<bool> p;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
if (value != _isEnabled)
{
_isEnabled = value;
if (CanExecuteChanged != null)
{
CanExecuteChanged(this, EventArgs.Empty);
}
}
}
}
public bool CanExecute(object parameter)
{
//return IsEnabled;
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_handler();
}
}
Related
I am following a course on Pluralsight called "Practical MVVM". In the 4th module of the course, the author was explaining how to use commands and that's when I had this strange issue. I had written almost the same code as it was in the video except for one difference. My local ICommand variable was declared as private instead of public.
Here is what happens when I click the button that has a Binding set to the method EditCoffee() that belongs to EditCommand command:
When ICommand EditCommand is declared as public or internal the method EditCoffee() is executed following the execution of Execute() and CanExecute() in CustomCommand class.
When ICommand EditCommand is declared as private or protected the method EditCoffee() is never executed and does not follow execution of Execute() and CanExecute() in CustomCommand class.
It's worth mentioning that LoadCommands() is triggered on in both scenarios.
CoffeeOverviewViewModel:
using JoeCoffeeStore.StockManagement.App.Services;
using JoeCoffeeStore.StockManagement.App.Utility;
using JoeCoffeeStore.StockManagement.Model;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Input;
namespace JoeCoffeeStore.StockManagement.App.ViewModel
{
public class CoffeeOverviewViewModel : INotifyPropertyChanged
{
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// Commands
private ICommand EditCommand { get; set; }
// Data Service
private CoffeeDataService _coffeeDataService;
// Properties
private ObservableCollection<Coffee> _coffees;
public ObservableCollection<Coffee> Coffees
{
get{ return _coffees; }
set
{
_coffees = value;
OnPropertyChanged();
}
}
private Coffee _selectedCoffee;
public Coffee SelectedCoffee
{
get { return _selectedCoffee; }
set
{
_selectedCoffee = value;
OnPropertyChanged();
}
}
// Constructor
public CoffeeOverviewViewModel()
{
_coffeeDataService = new CoffeeDataService();
LoadData();
LoadCommands();
}
private void LoadCommands()
{
EditCommand = new CustomCommand(EditCoffee, CanEditCoffee);
}
private void EditCoffee(object obj)
{
//TODO
}
private bool CanEditCoffee(object obj)
{
if (SelectedCoffee != null)
return true;
return false;
}
private void LoadData()
{
Coffees = new ObservableCollection<Coffee>(_coffeeDataService.GetAllCoffees());
}
}
}
CustomCommand.cs:
using System;
using System.Windows.Input;
namespace JoeCoffeeStore.StockManagement.App.Utility
{
public class CustomCommand : ICommand
{
private Action<object> _execute;
private Predicate<object> _canExecute;
public CustomCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public bool CanExecute(object parameter)
{
bool b = _canExecute == null ? true : _canExecute(parameter);
return b;
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
CoffeeOverviewView.xaml:
<StackPanel Grid.Row="7">
<Button Command="{Binding EditCommand}" Content="Edit coffee"/>
</StackPanel>
Solution structure:
Binding isn't magic. It's code that takes your XAML binding declaration:
<Button Command="{Binding EditCommand}"
and looks for a property of that name, EditCommand, in the DataContext of your class.
Your XAML view is a separate class than your ViewModel, so it makes sense that it can only access public properties on the ViewModel. Even internal properties are out of bounds, because it's the binding code that tries to access it, in the WPF libraries, not your own view code.
Simple RelayCommand defined as follows:
public class RelayCommand : IDelegateCommand
{
readonly Predicate<object> _canExecute;
readonly Action<object> _execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
: this(canExecute, execute, true)
{
}
public RelayCommand(Predicate<object> canExecute, Action<object> execute, bool isCommandAllowed)
{
_canExecute = canExecute;
_execute = execute;
IsAllowed = isCommandAllowed;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#region ICommand Members
public virtual bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public event EventHandler CanExecuteChanged = delegate { };
public virtual void Execute(object parameter)
{
_execute(parameter);
}
IDelegateCommand is defined as follows:
public interface IDelegateCommand : ICommand
{
void RaiseCanExecuteChanged();
}
Is bound to a WPF Button as follows:
<Button Command="{Binding StartSimulationCommand}" Content="Start Simulation"/>
And corresponding ViewModel usage of the Command is given as follows:
public class MainViewModel
{
// missing irrelevant bits
public ICommand StartSimulationCommand
{
get { return new RelayCommand(arg => true, arg =>
{
var inputValidationResponse = ValidateInputs();
if (!string.IsNullOrEmpty(inputValidationResponse))
{
_logger.Error(inputValidationResponse);
return;
}
// this method opens a websocket and if that operation is
// successful, property called IsWebSocketOpen is updated.
OpenWebSocketChannel();
// update command states
StopSimulationCommand.RaiseCanExecuteChanged();
});
}
}
public RelayCommand StopSimulationCommand
{
get { return new RelayCommand(arg => IsWebSocketOpened, arg => { CloseWebSocketChannel(); }); }
}
private bool _isWebSocketOpened;
public bool IsWebSocketOpened {
get { return _isWebSocketOpened; }
set { SetField(ref _isWebSocketOpened, value, "IsWebSocketOpened"); }
}
}
When I invoke StopSimulationCommand.RaiseCanExecuteChanged, the state of the button bound to StopSimulationCommand does not changed to enabled, even through the predicate for that command now returns true.
What did I miss?
You are creating a new instance of the RelayCommand in the setter of the StopSimulationCommand. You should create the command once in the constructor of the view model class:
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel ()
{
StopSimulationCommand = new RelayCommand(arg => IsWebSocketOpened, arg => { CloseWebSocketChannel(); });
}
public RelayCommand StopSimulationCommand { get; private set; }
}
I want to enable RibbonButton when textbox property text isn't null. Disable RibbonButton when textbox property text is null. I want to use CanExecute method in ICommand for it. How can I do it?
View:
<Custom:RibbonButton
LargeImageSource="..\Shared\img\save_diskete.png"
Label="Save"
Command="{Binding ButtonCommand}">
</Custom:RibbonButton>
ViewModel
class KomentarViewModel:BaseViewModel
{
#region Data
private ICommand m_ButtonCommand;
public ICommand ButtonCommand
{
get
{
return m_ButtonCommand;
}
set
{
m_ButtonCommand = value;
}
}
private string textKomentar;
public string TextKomentar
{
get
{
return this.textKomentar;
}
set
{
// Implement with property changed handling for INotifyPropertyChanged
if (!string.Equals(this.textKomentar, value))
{
textKomentar = value;
OnPropertyChanged("TextKomentar");
}
}
}
private ObservableCollection<Komentar> allCommentsInc;
public ObservableCollection<Komentar> AllCommentsInc
{
get
{
return allCommentsInc;
}
set
{
allCommentsInc = value;
OnPropertyChanged("AllCommentsInc");
}
}
public int idIncident { get; private set; }
public Incident incident { get; private set; }
#endregion
#region Constructor
public KomentarViewModel(int id)
{
CC_RK2Entities context = new CC_RK2Entities();
this.idIncident = id;
AllCommentsInc = new ObservableCollection<Komentar>(context.Komentar.Where(a => a.Incident_id == idIncident));
incident = context.Incident.Where(a => a.id == idIncident).First();
//ButtonCommand = new RelayCommand(new Action<object>(ShowMessage));
}
#endregion
#region Methods
//ukaz napsany text
public void ShowMessage(object obj)
{
//MessageBox.Show(obj.ToString());
MessageBox.Show(this.TextKomentar);
}
}
RelayCommand
namespace Admin.Shared.Commands
{
class RelayCommand : ICommand
{
private Action<object> _action;
public RelayCommand(Action<object> action)
{
_action = action;
}
#region ICommand Members
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
#endregion
}
}
You need to modify your RelayCommand class like this
class RelayCommand : ICommand
{
private Action<object> _action;
private Func<bool> _func;
public RelayCommand(Action<object> action,Func<bool> func)
{
_action = action;
_func = func;
}
public void RaiseCanExecuteChanged()
{
if(CanExecuteChanged!=null)
CanExecuteChanged(this,new EventArgs());
}
#region ICommand Members
public bool CanExecute(object parameter)
{
if (_func != null)
return _func();
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_action(parameter);
}
#endregion
}
Initialize ButtonCommand as
ButtonCommand = new RelayCommand((s) => ShowMessage(s),()=>!string.IsNullOrEmpty(TextKomentar));
RaiseCanExcuteChanged from the setter of Text property
public string TextKomentar
{
get
{
return this.textKomentar;
}
set
{
// Implement with property changed handling for INotifyPropertyChanged
if (!string.Equals(this.textKomentar, value))
{
textKomentar = value;
OnPropertyChanged("TextKomentar");
}
ButtonCommand.RaiseCanExecuteChanged();
}
}
implement this for canexecute:
public bool CanExecute(object parameter)
{if(thistext available)
return true;
else
return false;
}
Since, CanExecuteChanged is raised when the CanExecute method of an ICommand gets changed. it gets invoked when some command that could change canexecute.
and can execute changed should be changed to this:
public event EventHandler CanExecuteChanged {
add {
CommandManager.RequerySuggested += value;
}
remove {
CommandManager.RequerySuggested -= value;
}
}
EDIT
in your view model constructor:
m_ButtonCommand= new RelayCommand(Submit, CanSubmit);
now method for this submit:
private bool CanSubmit(object obj)
{
if(thistext available)
return true;
else
return false;
}
public void Submit(object _)
{//... code}
public event EventHandler CanExecuteChanged {
add {
CommandManager.RequerySuggested += value;
}
remove {
CommandManager.RequerySuggested -= value;
}
}
do it like this.
In straightforward words, you need the following:
Let's first create our own delegate command:
public class DelegateCommand : DelegateCommandBase
{
private Action _executeMethod;
private Func<bool> _canExecute;
public DelegateCommand(Action executeMethod)
: this(executeMethod, () => true) {}
public DelegateCommand(Action executeMethod, Func<bool> _canExecute): base()
{
if (executeMethod == null || _canExecute == null) {
throw new ArgumentNullException(nameof(executeMethod),
Resources.DelegateCommandDelegatesCannotBeNull);
}
_executeMethod = executeMethod;
_canExecute = _canExecute;
}
public void Execute() => _executeMethod();
public bool CanExecute() => _canExecute();
protected override void Execute(object parameter) => Execute();
protected override bool CanExecute(object parameter) => CanExecute();
public DelegateCommand ObservesProperty<T>(Expression<Func<T>> propertyExpression)
{
ObservesPropertyInternal(propertyExpression);
return this;
}
public DelegateCommand ObservesCanExecute(Expression<Func<bool>> canExecuteExpression)
{
_canExecute = canExecuteExpression.Compile();
ObservesPropertyInternal(canExecuteExpression);
return this;
}
}
Here, DelegateCommandBase is actually from Prism.Commands namespace.
If you don't use Prism as an MVVM framework for WPF, you can create your own copy of DelegateCommandBase (look for the solution here).
In your View Model, create a member with type DelegateCommand and initialize it in the constructor:
public class MyViewModel
{
private DelegateCommand _okCommand;
public DelegateCommand OkCommand
{
get => _okCommand;
set => SetProperty(ref _okCommand, value);
}
public MyViewModel()
{
OkCommand = new PrismCommands.DelegateCommand(OkCommandHandler,
OkCanExecuteCommandHandler);
}
private void OkCommandHandler()
{
// ...
}
// This is important part: need to return true/false based
// on the need to enable or disable item
private bool OkCanExecuteCommandHandler() =>
return some_condition_to_enable_disable_item;
}
Note: make sure to raise execution changed event, every time something changes that can affect some_condition_to_enable_disable_item condition behavior.
For example, in the case of Prism, you can call RaiseCanExecuteChanged method once a change happens related to the condition (in our case OkCommand.RaiseCanExecuteChanged();).
Small hint: for Telerik WPF Controls, you need to call InvalidateCanExecute() instead of RaiseCanExecuteChanged().
Finally, our XAML will look like this:
<Button x:Name="btnOk"
Content="Ok"
Command="{Binding OkCommand}"/>
Last time I used Microsoft.Practices.Prism.Commands namesapce from Microsoft.Practices.Prism.dll. Class DelegateCommand has own RaiseCanExecuteChanged() method. So the benifit is you don't have to write yout own implementation of ICommand.
XAML:
<StackPanel>
<CheckBox IsChecked="{Binding IsCanDoExportChecked}" />
<Button Command="{Binding ExportCommand}" Content="Export" />
</StackPanel>
ViewModel:
public class ViewModel
{
public DelegateCommand ExportCommand { get; }
public ViewModel()
{
ExportCommand = new DelegateCommand(Export, CanDoExptor);
}
private void Export()
{
//logic
}
private bool _isCanDoExportChecked;
public bool IsCanDoExportChecked
{
get { return _isCanDoExportChecked; }
set
{
if (_isCanDoExportChecked == value) return;
_isCanDoExportChecked = value;
ExportCommand.RaiseCanExecuteChanged();
}
}
private bool CanDoExptor()
{
return IsCanDoExportChecked;
}
}
I need to disable button for a while it running. I have this code:
RelayCommand.cs This is my command class.
class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
MainWindowViewModel.cs This is my command for binding.
private RelayCommand _getTextCommand;
public ICommand GetTextCommand
{
get
{
if (_getTextCommand == null)
{
_getTextCommand = new RelayCommand(
param => this.GetText(param),
param => true
);
}
return _getTextCommand;
}
}
MainWindow.xaml This is XAML code where i bind my command.
<Button x:Name="getTextButton" Command="{Binding GetTextCommand}" CommandParameter="{Binding ElementName=textTypeSelector, Path=SelectedIndex}"/>
This is the code i am launching in command:
public async void GetText(object o)
{
await Task.Factory.StartNew(() =>
{
// code
});
}
Try this: add a boolean property in view model and implement INotifyPropertyChanged in view model
private bool isEnable = true;
public bool IsEnable
{
get { return isEnable; }
set
{
isEnable = value;
NotifyPropertyChanged();
}
}
public async void GetText(object o)
{
await Task.Factory.StartNew(() =>
{
IsEnable = false;
});
IsEnable = true;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Bind it to button IsEnable property
<Button x:Name="abc"
Command="{Binding GetTextCommand}"
IsEnabled="{Binding IsEnable}" />
Set IsEnable whereever you want.
Add a boolean to your ViewModel to indicate that the command is executing and set the boolean in your GetText() method.
private bool _isRunning = false;
public async void GetText(object o)
{
await Task.Factory.StartNew(() =>
{
_isRunning = true;
CommandManager.InvalidateRequerySuggested();
// code
_isRunning = false;
CommandManager.InvalidateRequerySuggested();
});
}
public bool CanGetText(object o){
return ! _isRunning;
}
Then change your RelayCommand to the following
_getTextCommand = new RelayCommand(this.GetText,CanGetText);
The problem is that you are passing true for the CanExecute delegate. Pass it a method that will execute every time it needs evaluation, and within that method you can test to see whether the Command should be executable or otherwise.
Here is an implementation that I'm using. It doesn't need an additional property in the ViewModel.
public sealed class AsyncDelegateCommand : ICommand
{
private readonly Func<bool> _canExecute;
private readonly Func<Task> _executeAsync;
private Task _currentExecution;
public AsyncDelegateCommand(Func<Task> executeAsync)
: this(executeAsync, null)
{
}
public AsyncDelegateCommand(Func<Task> executeAsync, Func<bool> canExecute)
{
if (executeAsync == null) throw new ArgumentNullException("executeAsync");
_executeAsync = executeAsync;
_canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
if (_currentExecution != null && !_currentExecution.IsCompleted)
{
return false;
}
return _canExecute == null || _canExecute();
}
public async void Execute(object parameter)
{
try
{
_currentExecution = _executeAsync();
await _currentExecution;
}
finally
{
_currentExecution = null;
CommandManager.InvalidateRequerySuggested();
}
}
}
So in this particular MVVM implementation I'm doing, I need several commands. I really got tired of implementing the ICommand classes one by one, so I came up with a solution, but I don't know how good it is, so the input of any WPF expert here will be greatly appreciated. And if you could provide a better solution, even better.
What I did is a single ICommand class and two delegates which take an object as a parameter, one delegate is void (for OnExecute), the other bool (for OnCanExecute). So in the constructor of my ICommand (which is called by the ViewModel class) I send the two methods, and on each ICommand method I invoke the delegates' methods.
It works really good, but I'm not sure if this is a bad way to do it, or if there's a better way. Below is the complete code, any input will be greatly appreciated, even negative, but please be constructive.
ViewModel:
public class TestViewModel : DependencyObject
{
public ICommand Command1 { get; set; }
public ICommand Command2 { get; set; }
public ICommand Command3 { get; set; }
public TestViewModel()
{
this.Command1 = new TestCommand(ExecuteCommand1, CanExecuteCommand1);
this.Command2 = new TestCommand(ExecuteCommand2, CanExecuteCommand2);
this.Command3 = new TestCommand(ExecuteCommand3, CanExecuteCommand3);
}
public bool CanExecuteCommand1(object parameter)
{
return true;
}
public void ExecuteCommand1(object parameter)
{
MessageBox.Show("Executing command 1");
}
public bool CanExecuteCommand2(object parameter)
{
return true;
}
public void ExecuteCommand2(object parameter)
{
MessageBox.Show("Executing command 2");
}
public bool CanExecuteCommand3(object parameter)
{
return true;
}
public void ExecuteCommand3(object parameter)
{
MessageBox.Show("Executing command 3");
}
}
ICommand:
public class TestCommand : ICommand
{
public delegate void ICommandOnExecute(object parameter);
public delegate bool ICommandOnCanExecute(object parameter);
private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;
public TestCommand(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute.Invoke(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
#endregion
}
This is almost identical to how Karl Shifflet demonstrated a RelayCommand, where Execute fires a predetermined Action<T>. A top-notch solution, if you ask me.
public class RelayCommand : ICommand
{
private readonly Predicate<object> _canExecute;
private readonly Action<object> _execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
_canExecute = canExecute;
_execute = execute;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
This could then be used as...
public class MyViewModel
{
private ICommand _doSomething;
public ICommand DoSomethingCommand
{
get
{
if (_doSomething == null)
{
_doSomething = new RelayCommand(
p => this.CanDoSomething,
p => this.DoSomeImportantMethod());
}
return _doSomething;
}
}
}
Read more:
Josh Smith (introducer of RelayCommand): Patterns - WPF Apps With The MVVM Design Pattern
I have written this article about the ICommand interface.
The idea - creating a universal command that takes two delegates: one is called when ICommand.Execute (object param) is invoked, the second checks the status of whether you can execute the command (ICommand.CanExecute (object param)).
Requires the method to switching event CanExecuteChanged. It is called from the user interface elements for switching the state CanExecute() command.
public class ModelCommand : ICommand
{
#region Constructors
public ModelCommand(Action<object> execute)
: this(execute, null) { }
public ModelCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region ICommand Members
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return _canExecute != null ? _canExecute(parameter) : true;
}
public void Execute(object parameter)
{
if (_execute != null)
_execute(parameter);
}
public void OnCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
#endregion
private readonly Action<object> _execute = null;
private readonly Predicate<object> _canExecute = null;
}
I've just created a little example showing how to implement commands in convention over configuration style. However it requires Reflection.Emit() to be available. The supporting code may seem a little weird but once written it can be used many times.
Teaser:
public class SampleViewModel: BaseViewModelStub
{
public string Name { get; set; }
[UiCommand]
public void HelloWorld()
{
MessageBox.Show("Hello World!");
}
[UiCommand]
public void Print()
{
MessageBox.Show(String.Concat("Hello, ", Name, "!"), "SampleViewModel");
}
public bool CanPrint()
{
return !String.IsNullOrEmpty(Name);
}
}
}
UPDATE: now there seem to exist some libraries like http://www.codeproject.com/Articles/101881/Executing-Command-Logic-in-a-View-Model that solve the problem of ICommand boilerplate code.
#Carlo I really like your implementation of this, but I wanted to share my version and how to use it in my ViewModel
First implement ICommand
public class Command : ICommand
{
public delegate void ICommandOnExecute();
public delegate bool ICommandOnCanExecute();
private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;
public Command(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod = null)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute?.Invoke() ?? true;
}
public void Execute(object parameter)
{
_execute?.Invoke();
}
#endregion
}
Notice I have removed the parameter from ICommandOnExecute and ICommandOnCanExecute and added a null to the constructor
Then to use in the ViewModel
public Command CommandToRun_WithCheck
{
get
{
return new Command(() =>
{
// Code to run
}, () =>
{
// Code to check to see if we can run
// Return true or false
});
}
}
public Command CommandToRun_NoCheck
{
get
{
return new Command(() =>
{
// Code to run
});
}
}
I just find this way cleaner as I don't need to assign variables and then instantiate, it all done in one go.