Peter
Peter

Reputation: 249

Pass parameters to RelayCommand in code behind

I know that there are multiple posts with similar titles all over SOF and Google, but please bear with me for a minute.

I am following this article to create a context menu for my gridview: http://www.koaxkoaxkoax.com/ribbit/2010/09/creating-dynamic-menus-in-wpf.html

I create the HierarchicalDataTemplate in UserControl.Resources, I have an empty menu in the resources of the gridview, which I then reference in the actual context menu. The XAML (first part of the gridview) looks like this:

        <DataGrid.Resources>
            <Views:ViewMenuItemCollection x:Key="Menu">
                <Views:ViewMenuItem Text="foo"/>
                <Views:ViewMenuItem Text="bar"/>
            </Views:ViewMenuItemCollection>
        </DataGrid.Resources>
        <DataGrid.ContextMenu>
            <ContextMenu ItemsSource="{DynamicResource Menu}"/>
        </DataGrid.ContextMenu>

In the code behind I use FindResource to get a reference to the menu and create one ViewMenuItem-object that is on the same level as foo and bar. Then I iterate through a list and create one ViewMenuItem-object per list item and attach them as child objects. That looks just as I want to have it. But I can't get the actual functionality to work.

The inner part of the foreach-loop (where I create the child objects) looks like this:

ViewMenuItem seriesItem = new ViewMenuItem();
seriesItem.Text = series.ForcedName;
seriesItem.Command = new RelayCommand<Series>(p=>_view.SetSeriesExecute(p));             
_setSeriesMenuItem.Children.Add(seriesItem);

Especially the line containing p=>_view.SetSeriesExecute(p) is confusing me. I have found many many examples that look exactly like it. When I run my program and click on one of the child elements, the SetSeriesExecute method is properly called - but the paramter is always null. Not too surprising, because at no point I actually supply an object of type Series as parameter. I have tried to provide the parameter in the RelayCommand constructor like this: p=>_view.SetSeriesExecute(mySeriesObject). It compiles, but SetSeriesExecute is never called.

My goal is very simple (at least I think it is): When the program reacts to a click on an element in the context menu, the method (SetSeriesExecute) needs to know which item has actually been selected (=clicked on) by the user. Unfortunately I was not able to figure out where and how I can supply the parameters to SetSeriesExecute, despite 4 hours of serious research. And the fact that everyone else seems to understand the available examples doesn't make me feel particularly good about myself and I offer lifelong gratitude for every hint.

Best Peter

Upvotes: 2

Views: 925

Answers (1)

Khan
Khan

Reputation: 18162

What you're missing is the CommandParameter.

Try setting seriesItem.CommandParameter to whatever you would like to pass to the SetSeriesExecute method. p in p=>_view.SetSeriesExecute(mySeriesObject) will be that parameter.

Upvotes: 1

Related Questions