How is it possible that a WPF context menu is displayed outside the window?

windows, wpf

Solution

If you search on net for WPF context menu, you will find lots of articles stating `ContextMenu` doesn't belong to same Visual Tree as that of its parent.

They are not part of actual window, they are hosted in separate window. Just like you can have multiple windows in WPF over each other. Same holds true for ContextMenu and Popup's.

ContextMenu is a Popup only instead. If you are interested in looking at actual class responsible for handling it is `System.Windows.Controls.Primitives.Popup` class present in `PresentationFramework.dll`. Method `CreateWindow` gets called whenever context menu is opened.

And on close `DestroyWindow` method gets called to destroy the popUp window created to host content of ContextMenu.

So, whenever a context menu is opened/closed under the wraps a window is created and destroyed which is obviously not a part of main window but a separate window altogether which can go outside main window boundaries.

Problem

As I understand it, controls in WPF applications are not bound to system "window" resources (e.g., you can't find an handle for them with Spy++), unlike the old Windows Forms applications. So, how is that possible that part of those menus can be displayed outside the parent window? Why aren't they cut as soon as they reach the window borders? One possibility, of course, is that they aren't really WPF menus but, instead, standard Windows resources. That, however, collides with the fact that I can style one of those menus exactly like any other WPF control, and some quick look at the system messages log seems to confirm that as far as Windows knows they are, in fact, the same exact resource with the same exact handle. Then, I went further. I applied a rotation to the menu: ``` <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> ``` And this is the rather interesting result: So, what's going on?

Original source