20

I have a simple button that uses a command when executed, this is all working fine but I would like to pass a text parameter when the button is clicked.

I think my XAML is ok, but I'm unsure how to edit my RelayCommand class to receive a parameter:

<Button x:Name="AddCommand" Content="Add" Command="{Binding AddPhoneCommand}" CommandParameter="{Binding Text, ElementName=txtAddPhone}" /> 
public class RelayCommand : ICommand { private readonly Action _handler; private bool _isEnabled; public RelayCommand(Action handler) { _handler = handler; } 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; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { _handler(); } } 

3 Answers 3

15

Change Action to Action<T> so that it takes a parameter (probably just Action<object> is easiest).

private readonly Action<object> _handler; 

And then simply pass it the parameter:

public void Execute(object parameter) { _handler(parameter); } 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks that works great! I'm not that new to WPF but I am new to MVVM so commands are a new concept; but I can already see how they would help unit tests. So adding <object> isn't saying Action of type object but rather this delegate takes an object parameter?
@MichaelHarper yes, exactly, a delegate that takes one object parameter. You can see they've defined multiple action types along those lines: msdn.microsoft.com/en-us/library/018hxwa8.aspx
Thanks again, been a great help :D
7

You could just do

public ICommand AddPhoneCommand { get { return new Command<string>((x) => { if(x != null) { AddPhone(x); } }; } } 

Then, of course have your AddPhone:

public void AddPhone(string x) { //handle x } 

1 Comment

missing a closing parenthesis. return new Command<string>((x) => { if(x != null) { AddPhone(x); }});
4

You can simply do this (no change to RelayCommand or ICommand required):

private RelayCommand _addPhoneCommand; public RelayCommand AddPhoneCommand { get { if (_addPhoneCommand == null) { _addPhoneCommand = new RelayCommand( (parameter) => AddPhone(parameter), (parameter) => IsValidPhone(parameter) ); } return _addPhoneCommand; } } public void AddPhone(object parameter) { var text = (string)parameter; ... } public void IsValidPhone(object parameter) var text = (string)parameter; ... } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.