31

我有一个ContextMenu这样的:

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

我需要得到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);
    }
}

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

谢谢!

4

3 回答 3

63

这会给你你想要的东西

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;
    }
}

希望这可以帮助!!

于 2009-12-11T07:25:30.137 回答
9

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

于 2012-02-09T19:10:12.693 回答
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;
  }
于 2009-12-11T01:03:50.540 回答