在WPF中的某些情况下会切断上下文菜单

上下文菜单在不同的.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中使上下文菜单完全可见?

似乎在加载ContextMenu时,菜单的ScrollContentPresenter的大小不正确,剪切MenuItemItemPresenter (下面是显示问题的可视化树的删节版本)。

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

解决方法:

  

设置固定宽度时似乎停止了打扰。 仍然是Connect的一个很好的候选人。

我也能在.Net 4.5.1中重现这个问题。 也无法解决使用上述标记的解决方案。 InvalidateMeasure有时会导致空的上下文菜单,它会开始出现。 当我窥探上下文菜单时,发现菜单ItemsPanel大小计算完成得很好,但ScrollContentPresenter大小为0.Anyone面临类似问题。 我的解决方法是:

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

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