Leon Cullens
Leon Cullens

Reputation: 12476

How to pass CommandParameters to the ViewModel?

I have a command that should switch the current view when it's executed. I binded this command to my buttons like this:

<Button Style="{StaticResource TextButton}" Command="{Binding ViewModel:MainViewModel.OpenItemCommand}" CommandParameter="{Binding Link}"/>

I want to pass Link (the link of the currently selected article) to my command. My command is defined like this:

public class Command : ICommand
{
    public event EventHandler CanExecuteChanged;

    readonly Predicate<Object> _canExecute;
    readonly Action<Object> _executeAction;

    public Command(Predicate<Object> canExecute, Action<object> executeAction)
    {
        _canExecute = canExecute;
        _executeAction = executeAction;
    }
    public bool CanExecute(object parameter)
    {
        if (_canExecute != null)
            return _canExecute(parameter);
        return true;
    }

    public void UpdateCanExecuteState()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, new EventArgs());
    }

    public void Execute(object parameter)
    {
        if (_executeAction != null)
            _executeAction(parameter);
        UpdateCanExecuteState();
    }
}

In my ViewModel I have this:

public ICommand OpenItemCommand
{
    get
    {
        if (_openItemCommand == null)
        {
            _openItemCommand = new Command.Command(
                p => true,
                p => OpenItem(_HOW_DO_I_GET_THE_PARAMETER?_)
            );
        }
        return _openItemCommand;
    }
    set 
    {
        if (_openItemCommand != value)
        {
            _openItemCommand = value;
            RaisePropertyChanged("OpenItemCommand");
        }
    }
}

private void OpenItem(Uri link)
{
    throw new NotImplementedException();
}

When I create the command I need to pass the command parameter (the link) to the Execute method. But how do I get the value of this? I defined the CommandParameter in XAML, but I don't know how to access it.

I really searched through a huge amount of websites but I can't really find the answer.

Upvotes: 0

Views: 1743

Answers (2)

Phil
Phil

Reputation: 42991

You should look at the implementation of Prism's DelegateCommand or MVVM light's RelayCommand. With these you would write code like this:

public class ViewModel
{
    public ViewModel()
    {
        OpenItemCommand = new RelayCommand<string>(OpenItem);
    }

    public RelayCommand<string> OpenItemCommand { get; private set; }

    private void OpenItem(string link)
    {
        Debug.WriteLine(link);
    }
}

where string in this case is the type of the parameter.

I'm not sure where the link parameter is coming from but if it's from a control, the value of the control could be bound to a property of your view model, then you don't need a parameter, for example:

public class ViewModel
{
    public ViewModel()
    {
        OpenItemCommand = new RelayCommand(OpenItem);
    }

    public RelayCommand OpenItemCommand { get; private set; }

    public string Link { get; set; }

    private void OpenItem()
    {
        Debug.WriteLine(Link);
    }
}

Upvotes: 1

Emond
Emond

Reputation: 50672

replace

 p => OpenItem(_HOW_DO_I_GET_THE_PARAMETER?_)

with

 p => OpenItem(p)

that is what the p stands for: parameter

Upvotes: 1

Related Questions