据我了解,WPF应用程序中的控件未绑定到系统“窗口”资源(例如,您无法使用Spy ++找到它们的句柄),这与旧的Windows窗体应用程序不同。
那么,那些菜单的哪一部分可以显示在外面父窗口? 为什么他们一到达窗口边界就不会被切断?
当然,一种可能性是它们不是真正的WPF菜单,而是标准的Windows资源。然而,这与我可以完全像其他任何WPF控件一样设置其中一个菜单的事实相冲突,并且一些快速查看系统消息日志似乎证实,只要Windows知道它们实际上是具有相同精确句柄的完全相同的资源。
然后,我走得更远了。我在菜单上应用了一个旋转:
<Style TargetType="{x:Type ContextMenu}">
<Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-18.435"/>
<TranslateTransform/>
</TransformGroup>
</Setter.Value>
</Setter>
</Style>
这是一个相当有趣的结果:
那么,发生了什么?
答案 0 :(得分:4)
如果你在网上搜索WPF上下文菜单,你会发现很多文章都说明 ContextMenu
不属于与其父相同的Visual Tree。
它们不是实际窗口的一部分,它们托管在单独的窗口中。就像你可以在WPF中拥有多个窗口一样。对于ContextMenu和Popup来说也是如此。
ContextMenu只是一个Popup。如果您有兴趣查看负责处理的实际课程,System.Windows.Controls.Primitives.Popup
课程中会出现PresentationFramework.dll
课程。只要打开上下文菜单,就会调用方法CreateWindow
。
在关闭DestroyWindow
方法中调用以销毁为托管ContextMenu内容而创建的popUp窗口。
因此,无论何时在包装下打开/关闭上下文菜单,都会创建并销毁一个窗口,该窗口显然不是主窗口的一部分,而是一个单独的窗口,它可以在主窗口边界之外。
答案 1 :(得分:3)
Popup
对象是普通Window
上任何“浮动”上下文的基础,例如上下文菜单,下拉列表等。
实际上,Popup
实例会创建一个辅助Win32窗口,该窗口的目标是托管所需的WPF内容。实际上,Popup
类利用了HwndSource互操作:
这也很有用:
答案 2 :(得分:3)
但是,标准的Windows资源
它们确实是一个标准的Windows窗口。就像你的主窗口一样。顶级窗口,它们可以任意重叠其他窗口。
但是你可以看到后果,空域问题,本机Windows窗口无法旋转。它是一个基本的矩形,它最多可以给出一个形状。这可能是通过旋转矩形计算出来的形状,但是WPF并没有那么远。只能旋转内容。这在WPF中很容易做,内容只是绘制层,而不是像Winforms中的原生窗口,因此旋转它只需要旋转变换。但当然不能超越原生窗口的范围。