在WPF中,上下文菜单在某些情况下被切断

本文关键字:情况下 菜单 WPF 上下文 | 更新日期: 2023-09-27 18:17:15

上下文菜单在不同的。net框架中被截断。查看ZIP文件内的图片(有两个截图,一个来自XP,另一个来自Win7)。

我创建了一个简单的Visual Studio 2010解决方案,它再现了我的问题。

(http://www.mediafire.com/download.php?doq7gsh75qgvzwq).

在XP上似乎可以正常工作,但在Windows 7上就不行了。

如果目标。net框架是3.5(包括SP1),则该问题可以在Windows 7上重现(请参阅zip中的图像)。

如果我将目标框架更改为4.0,它在Windows 7上也可以正常工作。

是一个解决方案,使上下文菜单在Windows 7操作系统的。net Framework 3.5完全可见?

在WPF中,上下文菜单在某些情况下被切断

似乎当ContextMenu被加载时,菜单的ScrollContentPresenter大小不正确,剪切MenuItem s的ItemPresenter(以下是显示该问题的可视化树的简化版本)。

PopupRoot, Acutal Width: 219,027, Desired Width: 219,027
    Decorator, Acutal Width: 219,027, Desired Width: 219,027
        NonLogicalAdornerDecorator, Acutal Width: 219,027, Desired Width: 219,027
            ContextMenuProxy, Acutal Width: 219,027, Desired Width: 219,027
                SystemDropShadowChrome, Acutal Width: 214,027, Desired Width: 219,027
                    Border, Acutal Width: 214,027, Desired Width: 214,027
                        Grid, Acutal Width: 212,027, Desired Width: 212,027
                            Rectangle, Acutal Width: 28,000, Desired Width: 32,000
                            Rectangle, Acutal Width: 1,000, Desired Width: 31,000
                            Rectangle, Acutal Width: 1,000, Desired Width: 32,000
                            ScrollViewer, Acutal Width: 210,027, Desired Width: 212,027
                                Grid, Acutal Width: 210,027, Desired Width: 210,027
                                    Border, Acutal Width: 210,027, Desired Width: 210,027
                                        ScrollContentPresenter, Acutal Width: 210,027, Desired Width: 210,027
                                            ItemsPresenter, Acutal Width: 241,047, Desired Width: 245,047

当菜单加载时,使ContextMenu的视觉根(PopupRoot)的测量无效应该导致布局更新以显示ItemsPresenter的正确边界。

菜单的Load事件的处理程序:

private void mainMenu_Loaded(object sender, RoutedEventArgs e)
{
    if (sender != null)
    {
        ContextMenu menu = sender as ContextMenu;
        if (menu != null)
        {
           // get the visual root for the context menu
           var root = (FrameworkElement)GetVisualTreeRoot(menu);
           // invalidate the menu's layout
           root.InvalidateMeasure();
        }             
    }
}

GetVisualTreeRoot方法:

private DependencyObject GetVisualTreeRoot(DependencyObject control)
{
    DependencyObject parent = VisualTreeHelper.GetParent(control);
    if (parent != null)
    {
        return GetVisualTreeRoot(parent);
    }
    else
    {
        return control;
    }
}

变通方法:

<ContextMenu x:Name="mainMenu" Width="300" >

当设置一个固定的宽度时,它似乎停止了困扰。

我也能在。net 4.5.1中重现这个问题。也不能用上面标注的溶液解决。invalidatemmeasure仍然会导致空的上下文菜单有时,它开始出现。当我窥探上下文菜单时,发现菜单ItemsPanel的大小计算做得很好,但是ScrollContentPresenter的大小是0。任何面临类似问题的人。我的解决方法是:

    private static void ContextMenuOnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        var menu = (ContextMenu)sender;
        if (menu.HasItems)
        {
            menu.MinHeight = menu.Items.Count * 25;
        }
        menu.Loaded -= ContextMenuOnLoaded;
    }

不确定这是否是最好的解决方案。但为什么会发生这种情况也令人惊讶。