Getting a parameter from XAML in a command

May 6, 2010 at 4:06 PM

I would like to route a group of buttons to the same command, being able to discriminate which of them has been pressed in some way.

What is the simplest way to do this, please?

Coordinator
May 6, 2010 at 4:25 PM

You can set/bind each Button's Command property to the same ICommand instance.  Then set/bind each Button's CommandParameter property to a unique value, such as a String or a number.  In the ICommand, inspect the 'parameter' argument to see which Button caused the command to execute.

May 6, 2010 at 4:47 PM

I am using MVVM foundation and my code block looks like this:

        private ICommand cmdSelectProduct;

        public ICommand SelectProductCommand
        {
            get
            {
                if (cmdSelectProduct == null)
                {
                    cmdSelectProduct = new RelayCommand(SelectProduct);
                }
                return cmdSelectProduct;
            }
        }

        private void SelectProduct()
        {
            SelectedProduct = ???;
            // Fire an event for UI changes
            OnSelectProduct();
        }

Maybe I should not be using RelayCommand for this job and create a class implementing ICommand, right?

May 6, 2010 at 4:51 PM
Edited May 6, 2010 at 4:55 PM

I think you simply need to change SelectProduct to this:

 

 

private void SelectProduct(object parameter){

    string choice = parameter as string;
   if(choice == null){return;}
   switch(choice){
    .....
   }
}

 

<Button Command={Binding Path=SelectProductCommand} CommandParameter="mychoice">Button To Make My Choice</Button>

 

May 6, 2010 at 4:55 PM

no, it complains that an Action is not a method group.

May 6, 2010 at 4:59 PM
Edited May 6, 2010 at 5:08 PM

Works for me in this code:

        public RelayCommand SetStatusCommand
        {
            get
            {
                if (setStatusCommand == null)
                {
                    setStatusCommand = new RelayCommand(SetStatus);
                }
                return setStatusCommand;
            }
        }

        protected void SetStatus(object status)
        {
            this.Status = (SubjectStatus)status;
        }


Although I'm passing an Enum value as the parameter, using a static resource.

<mod:SubjectStatus x:Key="statusAbsent">Absent</mod:SubjectStatus>

<Button Name="buttonAbsent" Command="{Binding SetStatusCommand}" CommandParameter="{StaticResource statusAbsent}">_Absent</Button>

 

 

 

                    <Button Name="buttonAbsent"
                            Command="{Binding SetStatusCommand}"
                            CommandParameter="{StaticResource statusAbsent}">_Absent</Button>
May 6, 2010 at 5:12 PM

Thank you. I tried your code, but still have the same error.

Might be some dependency, like the .net framework version (I am using Visual Studio 2010) or maybe the MVVM foundation framework (mine  is 1.0.0.0).

May 6, 2010 at 5:15 PM
Ah sorry you will need to make sure you use RelayCommand<object>, I have been using the old code from Josh's demo app (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030) where the RelayCommand takes and Action<object> by default, I need to update my stuff. Or you could use RelayCommand<string> and have private void SelectProduct(string param){...}.
May 11, 2010 at 10:21 AM
Edited May 11, 2010 at 10:56 AM

Ah, yes, it worked for me after a little editing, thanks.

Here it is for reference.

 

    #region SelectProduct [command]
    private RelayCommand<object> cmdSelectProduct;

    public RelayCommand<object> SelectProductCommand
    {
        get
        {
            if (cmdSelectProduct == null)
            {
                cmdSelectProduct = new RelayCommand<object>(SelectProduct);
            }
            return cmdSelectProduct;
        }
    }

    private void SelectProduct(object param)
    {
        string prod = param as string;
        // fire event for UI
        OnSelectProduct();
    }
    #endregion