Nov 30, 2015

wpf relaycommand with parameter

One of the things I frequently run across while coding in WPF is the need to pass a parameter to a bound command. Typically on the view model side, the command is handled by a Relay Command, but I wanted a bit more type safety than just having take any arbitrary object. So with a little modification, the Relay Command can be made into a generic and we’ll be able to gain all the nice type safety checks at compile time.
The source file is available for download and has been reproduced below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace System.Windows.Input
{
    public class RelayCommand<T> : ICommand
    {
        #region Fields
 
        private readonly Action<T> _execute = null;
        private readonly Predicate<T> _canExecute = null;
 
        #endregion
 
        #region Constructors
 
        /// <summary>
        /// Creates a new command that can always execute.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        public RelayCommand(Action<T> execute)
            : this(execute, null)
        {
        }
 
        /// <summary>
        /// Creates a new command with conditional execution.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        /// <param name="canExecute">The execution status logic.</param>
        public RelayCommand(Action<T> execute, Predicate<T> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");
 
            _execute = execute;
            _canExecute = canExecute;
        }
 
        #endregion
 
        #region ICommand Members
 
        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute((T)parameter);
        }
 
        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (_canExecute != null)
                    CommandManager.RequerySuggested += value;
            }
            remove
            {
                if (_canExecute != null)
                    CommandManager.RequerySuggested -= value;
            }
        }
 
        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }
 
        #endregion
    }
}
Using the parameterized Relay Command is straight forward. The only not so nice part is that commands that take in no parameters must take an object type which won’t be used. Here’s an example of the Relay Command with no parameters:
ViewModel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public ICommand NoParameterCommand
{
get
{
if (null == _noParameterCommand)
_noParameterCommand = new RelayCommand<object>(ExecuteNoParameterCommand);
 
return _noParameterCommand;
}
}
 
private void ExecuteNoParameterCommand(object notUsed)
{
}
View
1
<Button Command="{Binding Path=NoParameterCommand}"/>
While commands with no parameters are slightly more troublesome, commands with parameters are quite easy now:
ViewModel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public enum Fruit
{
    Apple,
    Banana,
    Cantaloupe,
}
 
private RelayCommand<Fruit> _fruitParameterCommand;
public ICommand FruitParameterCommand
{
    get
    {
        if (null == _fruitParameterCommand)
            _fruitParameterCommand = new RelayCommand<Fruit>(ExecuteFruitParameterCommand);
 
        return _fruitParameterCommand;
    }
}
 
private void ExecuteFruitParameterCommand(Fruit fruit)
{
}
View
1
<Button Command="{Binding Path=FruitParameterCommand}" CommandParameter="{x:Static local:Fruit.Banana}"/>
Remember to include the namespace reference local to the XAML file.
http://www.kellydun.com/wpf-relaycommand-with-parameter/

0 comments:

Post a Comment

Nam Le © 2014 - Designed by Templateism.com, Distributed By Templatelib