在代码中获取上下文菜单的所有者

Car*_*rlo 27 wpf contextmenu parent

ContextMenu喜欢这样的:

<StackPanel Orientation="Horizontal">
    <StackPanel.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Delete" Click="OnDeleteClicked" />
        </ContextMenu>
    </StackPanel.ContextMenu>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)

我需要获得StackPanel拥有该实例的实例ContextMenu.我已经尝试过了:

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

    while (!(parent is StackPanel))
    {               
        parent = (FrameworkElement)LogicalTreeHelper.GetParent(parent);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在获得ContextMenuPopup父级之后VisualTreeHelper,它变为null,与之相同,它在获取之前变为null StackPanel.有关如何做到这一点的任何想法?

谢谢!

vik*_*iky 55

这将给你你想要的确切的东西

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!!


Ama*_*duh 7

ContextMenus和Popups的可视化树的工作方式略有不同.您可以使用它ContextMenu.PlacementTarget来获取StackPanel.这里有MSDN上提供更多信息:http://msdn.microsoft.com/en-us/library/system.windows.controls.contextmenu.placementtarget.aspx


Ara*_*and 1

上下文菜单有自己的可视化树,尝试从事件处理程序中调用它,如下所示:-

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;
  }
Run Code Online (Sandbox Code Playgroud)