Carlo
Carlo

Reputation: 25969

Get owner of context menu in code

I have a ContextMenu like this:

<StackPanel Orientation="Horizontal">
    <StackPanel.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Delete" Click="OnDeleteClicked" />
        </ContextMenu>
    </StackPanel.ContextMenu>
</StackPanel>

And I need to get the instance of the StackPanel that owns that ContextMenu. I already tried this:

private void OnDeleteClicked(object sender, System.Windows.RoutedEventArgs e)
{
    FrameworkElement parent = e.OriginalSource as FrameworkElement;

    while (!(parent is StackPanel))
    {               
        parent = (FrameworkElement)LogicalTreeHelper.GetParent(parent);
    }
}

But after getting the ContextMenu Popup parent, it gets null, same with the VisualTreeHelper, it gets to null before getting the StackPanel. Any idea on how to do this?

Thanks!

Upvotes: 32

Views: 22250

Answers (3)

Amanduh
Amanduh

Reputation: 1243

The visual tree for ContextMenus and Popups works a little differently. You can use ContextMenu.PlacementTarget to get the StackPanel. There is more information available on MSDN here: http://msdn.microsoft.com/en-us/library/system.windows.controls.contextmenu.placementtarget.aspx

Upvotes: 9

viky
viky

Reputation: 17689

this will give you the exact thing you want

private void OnDeleteClicked(object sender, System.Windows.RoutedEventArgs e)
{
    MenuItem mnu = sender as MenuItem;
    StackPanel sp = null;
    if(mnu!=null)
    {
        sp = ((ContextMenu)mnu.Parent).PlacementTarget as StackPanel;
    }
}

Hope this helps!!

Upvotes: 64

Aran Mulholland
Aran Mulholland

Reputation: 23945

the context menu has its own visual tree, try this calling this from your event handler like so :-

StackPanel stackPanel = GetStackPanelItemFromContextMenu((FrameworkElement)sender, yourStackPanel);

  private StackPanel GetStackPanelItemFromContextMenu(FrameworkElement sender, StackPanel stackPanel) {
     Point menuClickPoint = ((sender as FrameworkElement).Parent as ContextMenu).TranslatePoint(new Point(0, 0), stackPanel);

     // get the first potential object that was hit   
     DependencyObject obj = stackPanel.InputHitTest(menuClickPoint) as DependencyObject;

     // cycle up the tree until you hit the StackPanel
     while (obj != null && !(obj is StackPanel)) {
        obj = VisualTreeHelper.GetParent(obj);
     }

     return obj as StackPanel;
  }

Upvotes: 1

Related Questions