Mouse hit the popup menu of transparent background in xaml

Today I ran into a very strange problem:

I have a popup menu that opens when I hover over the image. The popup menu is located to the right of the image.

this template popup looks like a rectangle with a small arrow pointing to the image

the menu contains elements that are clickable, so I need to be able to move the mouse from the image to the menu without closing between them, and here I am confused: if I move the mouse directly above the end of the arrow and then the menu, everything works fine. If I move the mouse over the transparent space between the image and the menu (above or below the arrow), the menu disappears.

Here is the template for the menu:

<Popup AllowsTransparency="True" Name="c_popup" Width="300" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right"> <Grid Background="Transparent"> <Grid.ColumnDefinitions> <ColumnDefinition Width="10" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Path Data="M 0 10 L 10 0 10 20 Z" Stroke="#252C37" Fill="#252C37" Margin="0,18,0,0" Grid.Column="0" /> <Grid Grid.Column="1" Background="#252C37"> <TextBlock Text="{Binding Name}" Margin="20,10,0,0" FontSize="18" Foreground="White" HorizontalAlignment="Stretch" VerticalAlignment="Top" TextWrapping="WrapWithOverflow" /> </Grid> </Grid> </Popup> 

you will notice that I specifically put Background = " Transparent " and not Null (I am aware of the effect of this as on hitTesting, see this question )

The funny thing is, though: if I put Background = "# 01000000", it works as expected. (And I get almost what I want, as it is an almost transparent background)

but I still would like to know what is happening there ...

I suspect this has something to do with the fact that this is a pop-up menu. I believe that WPF is doing something to remove hitTesting on any surface that is transparent in the popup menu, or when the background is zero (which is expected), or even if it is specifically set to transparency (not expected). Can anyone confirm this?

+4
source share
1 answer

Convert my comment to response.

This is more of a "Windows" problem than WPF, especially on the AllowTransparency="True" path at the window level, forcing the system to ignore the element for mouseover events when Background="Transparent" or Opacity="0" on the element.

A detailed explanation of this behavior can be found here.

Adding an MSDN response in case the link is missing later:

Windows supports transparency at the HWND level with a feature called layered windows.
Laminated windows are represented by a raster image. The operating system (OS) displays a bitmap when necessary.
In order for the operating system to respond very quickly to mouse movement, Windows uses a dedicated Raw input stream (RIT). RIT runs in the kernel and processes singles from the mouse hardware. RIT can scan through the HWND hierarchy to determine which window the mouse is in. For regular windows, RIT checks the position of the mouse relative to the rectangle of the window. For layered windows, RIT looks at a bitmap that indicates the contents of the window and checks for effective transparency at that location. Effective transparency may depend on opacity, color, and alpha. If the pixel is 100% transparent, RIT skips the window and continues to watch. This point is the reason that the MouseMove event does not fire. If the Background of window and control are transparent, all the pixels that represent this control (Canvas in your example) in layered windows are completely transparent. As described above, RIT will skip them and never send a WM_MOUSEMOVE message. Therefore, if you want to display the control only when the mouse is finished, and otherwise a transparent window, you must make the control not 100% transparent.

There is something note in this case, although the Popup is inside the Window , which does not have AllowTransparency="True" , Popup generates the Chrome-less window itself, and AllowTransparency="True" in Popup affects this new chromeless -Window as well as indicated in the MSDN link above.

If this control was a standard control, for example Button / Rectangle ..., then just setting Background="Transparent" will make it work fine and will not have this problem.

+5
source

Source: https://habr.com/ru/post/1489435/


All Articles