Generic RelayCommand
1using System;
2using System.Windows.Input;
3
4namespace SpiritMVVM
5{
6 /// <summary>
7 /// The <see cref="RelayCommand{T}"/> class assigns an <see cref="Action{T}"/> delegate to the <see cref="Execute"/>
8 /// method and a <see cref="Func{T, T}"/> delegate to the <see cref="CanExecute"/> method,
9 /// allowing <see cref="ICommand"/> objects to be implemented completely from within a View-Model.
10 /// </summary>
11 /// <typeparam name="TParam">
12 /// Determines the parameter type that will be passed in to your
13 /// <see cref="Action{T}"/> and <see cref="Func{T, T}"/> delegates.
14 /// </typeparam>
15 public class RelayCommand<TParam> : ICommand, IRaiseCanExecuteChanged
16 {
17 #region Private Fields
18
19 private readonly Func<TParam, bool> _canExecute;
20 private readonly Action<TParam> _execute;
21
22 #endregion Private Fields
23
24 #region Constructors
25
26 /// <summary>
27 /// Create a new <see cref="RelayCommand"/> with the given execution delegate.
28 /// </summary>
29 /// <param name="execute">The <see cref="Action"/> to execute when the
30 /// <see cref="Execute"/> method is called.</param>
31 public RelayCommand(Action<TParam> execute)
32 : this(execute, null)
33 { }
34
35 /// <summary>
36 /// Create a new <see cref="RelayCommand"/> with the given execution delegate.
37 /// </summary>
38 /// <param name="execute">The <see cref="Action"/> to execute when the
39 /// <see cref="Execute"/> method is called.</param>
40 /// <param name="canExecute">The <see cref="Func{T, T}"/> to execute
41 /// when the <see cref="CanExecute"/> method is queried.</param>
42 public RelayCommand(Action<TParam> execute, Func<TParam, bool> canExecute)
43 {
44 if (execute == null)
45 throw new ArgumentNullException("execute");
46
47 _execute = execute;
48 _canExecute = canExecute;
49 }
50
51 #endregion Constructors
52
53 #region ICommand Implementation
54
55 /// <summary>
56 /// Event which is raised when the command's ability to be executed changes.
57 /// </summary>
58 public event EventHandler CanExecuteChanged = null;
59
60 /// <summary>
61 /// Determine if the command can be executed in its current state.
62 /// </summary>
63 /// <param name="parameter">An optional parameter.</param>
64 /// <returns>Returns True if the command can be executed. Otherwise, false.</returns>
65 public bool CanExecute(object parameter)
66 {
67 var canExecuteHandler = _canExecute;
68 if (canExecuteHandler != null)
69 {
70 return canExecuteHandler((TParam)parameter);
71 }
72
73 return true;
74 }
75
76 /// <summary>
77 /// Execute the command's delegate method.
78 /// </summary>
79 /// <param name="parameter">An optional parameter.</param>
80 public void Execute(object parameter)
81 {
82 var executeHandler = _execute;
83 if (executeHandler != null)
84 {
85 executeHandler((TParam)parameter);
86 }
87 }
88
89 #endregion ICommand Implementation
90
91 #region IRaiseCanExecuteChanged Implementation
92
93 /// <summary>
94 /// Raise the <see cref="ICommand.CanExecuteChanged"/> event.
95 /// </summary>
96 public void RaiseCanExecuteChanged()
97 {
98 var handler = CanExecuteChanged;
99 if (handler != null)
100 {
101 handler(this, EventArgs.Empty);
102 }
103 }
104
105 #endregion IRaiseCanExecuteChanged Implementation
106 }
107}