Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
1285
Create common context menu in WPF
posted

This is more of a general WPF question than your controls, I tried posting on Expert Exchange and Stack Overflow without any success.  So I thought you might be able to help.

n my app I have many grids (Infragistics). I would like to create a context menu that will implement many of the common functions ie: delete, save layout, etc. and if a specific grid needs more than the common functions be able to add to the menu for that grid. I would like to create one context menu and not have to repeat the same code throughout project.

I have no idea on how to accomplish this. Possible? Example xaml and/or code will be helpful.

Thanks a bunch,

Rick

Parents Reply Children
  • 1285
    Verified Answer
    posted in reply to [Infragistics] Curtis Taylor

    Here is my solution I came up with:

    I created  a resource dictionary with code behind to hold my context menu (http://stackoverflow.com/questions/92100/is-it-possible-to-set-code-behind-a-resource-dictionary-in-wpf-for-event-handling):
    <

    resourcedictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"><ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                       xmlns:sys="clr-namespace:System;assembly=mscorlib"
                       x:Class="DCS.CAPPS.ResourceDictionaries.GridContextMenu"
                       x:ClassModifier="public">
       <x:Array Type="{x:Type sys:Object}" x:Key="GridContextMenu">
           <MenuItem Header="Test" Name="Test" Click="Test_Click"/>
       </x:Array>
    </ResourceDictionary>

    GRID:
    <igDP:XamDataGrid.ContextMenu>
                               <ContextMenu Opened="ContextMenu_Opened">
                                   <ContextMenu.ItemsSource>
                                       <CompositeCollection>
                                           <CollectionContainer Collection="{StaticResource GridContextMenu}"/>
                                       </CompositeCollection>
                                   </ContextMenu.ItemsSource>
                               </ContextMenu>
                           </igDP:XamDataGrid.ContextMenu><igDP:XamDataGrid.ContextMenu>
                               <ContextMenu Opened="ContextMenu_Opened">
                                   <ContextMenu.ItemsSource>
                                       <CompositeCollection>
                                           <CollectionContainer Collection="{StaticResource GridContextMenu}"/>
                                       </CompositeCollection>
                                   </ContextMenu.ItemsSource>
                               </ContextMenu>
                           </igDP:XamDataGrid.ContextMenu>

    To get the to the grid in the event handler I needed to do this in the context opened handler:
    private void ContextMenu_Opened(object sender, RoutedEventArgs e)
           {
               ContextMenu c = sender as ContextMenu;
               CompositeCollection col = c.ItemsSource as CompositeCollection;
               CollectionContainer col2 = col[0] as CollectionContainer;

               foreach (object item in col2.Collection)
               {
                   MenuItem m = item as MenuItem;
                   if (m != null)
                   {
                       m.CommandParameter = c;
                   }
               }
           }
    And in the click handler in the resource code:
    private void Test_Click(object sender, RoutedEventArgs e)
           {
               MenuItem mi = sender as MenuItem;
               ContextMenu cm = mi.CommandParameter as ContextMenu;
               XamDataGrid grid = cm.PlacementTarget as XamDataGrid;

               if (grid != null)
                   MessageBox.Show("Works");
               else
                   MessageBox.Show("Does Not work");
           }