【问题标题】:Context menu is cut in some situations in WPF在 WPF 中的某些情况下,上下文菜单被剪切
【发布时间】:2012-01-14 19:30:18
【问题描述】:

上下文菜单在不同的 .NET Framework 中被截断。查看 ZIP 文件中的图片(有两张截图,一张来自 XP,另一张来自 Win7)。

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

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

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

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

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

在 Windows 7 操作系统上的 .NET Framework 3.5 中,是否有使上下文菜单完全可见的解决方案?

【问题讨论】:

  • 没人?拜托,我需要帮助:)
  • 奇怪的行为……确实如你所说。对我来说奇怪的是,如果在 Visual Studio 中运行,它发生得最多。当 VS 没有运行时,它仍然会发生。对我来说,这是 Connect 的理想选择。
  • 无法重现。可能是因为我安装了 .Net 4.5?
  • 无法?请在项目目标框架中设置 .NET Framework 3.5,然后重试。仅在 Windows 7 中。不是 XP。
  • 是的,我将目标框架设置为 3.5,在 Windows 7 上运行。

标签: c# .net wpf .net-3.5 contextmenu


【解决方案1】:

我也可以在 .Net 4.5.1 中重现此问题。 使用上述标记的解决方案也无法解决。 InvalidateMeasure 仍然导致 有时是空的上下文菜单,它开始出现。当我窥探上下文菜单时, 发现菜单 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;
    }

不确定这是否是最佳解决方案。但为什么会发生同样令人惊讶。

【讨论】:

    【解决方案2】:

    似乎在加载 ContextMenu 时,菜单的 ScrollContentPresenter 大小不正确,剪切了 MenuItems 的 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 的正确边界。

    菜单加载事件的处理程序:

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

    【讨论】:

    • 我奖励你是因为这是一个很好的解决方法。如果可行的话,我会在几天后尝试。如果是,答案将被标记为已接受。感谢您的耐心等待。
    【解决方案3】:

    解决方法:

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

    设置固定宽度时似乎不再麻烦。 仍然是 Connect 的理想候选者。

    【讨论】:

    • 这不是解决方案。如果我插入长词会怎样?
    • 是的……它不是。这是一种解决方法。由于这似乎是一种不正确的行为,需要 MS 进行修复,因此您可能得到的只是解决方法:o)
    • 当然,你也可以限制菜单项的大小,让它们必须将文本包裹在里面。
    猜你喜欢
    • 2012-01-28
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多