WPF 上下文菜单怎么可能显示在窗口外?

dan*_*eds 3 windows wpf

据我了解,与旧的 Windows 窗体应用程序不同,WPF 应用程序中的控件不绑定到系统“窗口”资源(例如,您无法使用 Spy++ 找到它们的句柄)。

那么,这些菜单的一部分怎么可能显示在外面在父窗口呢?为什么它们在到达窗口边界时不立即切断?

当然,一种可能性是它们并不是真正的 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>
Run Code Online (Sandbox Code Playgroud)

这是相当有趣的结果:

菜单被裁剪成矩形

发生什么了?

Roh*_*ats 5

如果您在网络上搜索 WPF 上下文菜单,您会发现很多文章都声明ContextMenu不属于与其父级相同的 Visual Tree

它们不是实际窗口的一部分,它们托管在单独的窗口中。就像您可以在 WPF 中拥有多个相互重叠的窗口一样。ContextMenu 和 Popup 也是如此。

ContextMenu 只是一个弹出窗口。如果你有兴趣在寻找负责处理它实际的类是System.Windows.Controls.Primitives.Popup存在于类PresentationFramework.dll。方法CreateWindow每当打开上下文菜单时都会调用。

并且在 closeDestroyWindow方法被调用以销毁为承载 ContextMenu 的内容而创建的弹出窗口。

因此,每当在包装下打开/关闭上下文菜单时,都会创建和销毁一个窗口,该窗口显然不是主窗口的一部分,而是一个可以超出主窗口边界的单独窗口。