有没有人知道我如何确定ContextMenu
什么时候会因为太靠近屏幕边缘而自动调整位置?
我的情况是,我有一个ContextMenu
,它有2个圆角和2个方角。当菜单向下打开时,我将底部2圆化,如果菜单向上打开,我将顶部2圆化。问题是,我还没有找到一个事件或属性绑定到它,告诉我菜单何时自动改变方向。
这里有一些简单的示例代码可以尝试。如果你在窗口位于屏幕顶部时单击,则菜单会向下移动。如果你将窗口移到屏幕底部,则菜单会向上移动。
<Window x:Class="menuRedirection.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="100" Width="200">
<DockPanel Name="panel" ContextMenuOpening="DockPanel_ContextMenuOpening">
<DockPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="item"/>
<MenuItem Header="item"/>
<MenuItem Header="item"/>
<MenuItem Header="item"/>
</ContextMenu>
</DockPanel.ContextMenu>
<Rectangle DockPanel.Dock="Bottom" Name="menuTarget" Fill="Red" Height="10"/>
<TextBlock DockPanel.Dock="Top" Text="right click for context menu"/>
</DockPanel>
</Window>
private void DockPanel_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
ContextMenuService.SetPlacement(panel, PlacementMode.Bottom);
ContextMenuService.SetPlacementTarget(panel, menuTarget);
}
下面是真实的的应用程序看起来像这样,你可以看到我的问题,需要知道调整我的圆角。
2条答案
按热度按时间toiithl61#
据我所知,这是不可能的。
使用JustDecompile,我跟踪这个功能到
Popup
类中的UpdatePosition
方法。_secHelper
是PopupSecurityHelper
类型的helper类,似乎只是一个内部helper...并且,这些都不会导致事件甚至公共属性被更改。Here is an MSDN article explaining how popup positioning is determined in general("当弹出窗口遇到屏幕边缘时“描述了您的场景)。
然而,this article解释了如何使用
CustomPopupPlacementCallback
来覆盖这些行为。然而,这仍然使用了PopupPrimaryAxis
,它应该在必要时翻转菜单,并将导致同样的问题。我能想到的唯一的另一件事是,你可以查看
PlacementRectangle
,也许轮询的大小和位置类似于UpdatePosition
如何做的事情...或者只是检查弹出本身,就像UpdatePosition一样。但是这是一个私有方法,所以,任何你试图模仿的逻辑都可能在框架的未来版本中改变。
更新
此外,您可能会尝试bastardizing
PointToScreen
或PointFromScreen
,但这将是非常复杂的代码,如果它的工作...vsmadaxz2#
我无法找到一个真正的WPF解决方案,但Justin的评论引导我沿着实验的道路,将菜单的位置与PlacementTarget的位置进行比较。
第一步是订阅contextMenu.loaded事件(该事件在布局被处理后但在屏幕上完全可见之前触发)。
然后,当它触发时,我可以判断菜单是否在内部切换到我所请求的placementMode的备用位置。如果是相反的,那么我继续并相应地调整我的圆角。
注意:我最初使用了getWindowRect并将菜单Rect与目标的Rect进行了比较,但发现菜单Rect总是返回前一个示例的位置。为了避免这个问题,我现在获取相关屏幕的workingArea并手动查看菜单是否适合。
注意2:确保你的菜单模板在反转显示和正常显示时产生相同的窗口高度。否则,你的计算可能会出错,因为getWindowRect返回的是最后一个菜单的大小。
评价方法:
最终结果: