在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
的大小不正确,剪切MenuItem
的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
)的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; }
不确定它是否是最佳解决方案。 但为什么会发生这种情况也令人惊讶。