2

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

Peter
  • 249
  • 3
  • 11

1 Answers1

1

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.

Khan
  • 17,904
  • 5
  • 47
  • 59
  • +1, or apply a binding to the `CommandParameter`. In fact, both should be bound. – user7116 Feb 20 '13 at 18:03
  • I have added `Series CommandParameter` to my `ViewMenuItem`-class. But the parameter in `SetSeriesExecute` is still null. How would SetSeriesExecute know to look for this Property anyway? – Peter Feb 20 '13 at 18:05
  • What is `series.ForcedName` ? – Khan Feb 20 '13 at 18:18
  • `ForcedName` is a string property and is used as the text of the menu item – Peter Feb 20 '13 at 18:28
  • I thought text is set here: `` – Khan Feb 20 '13 at 19:04
  • Yes, those are different items. In my example I create 2 items in XAML and one item with many child items at runtime. My question is how I can pass parameters at runtime without XAML databinding. – Peter Feb 21 '13 at 01:03
  • @sixlettervariables: Can you give me a short example of what I have to do? – Peter Feb 21 '13 at 01:03