鼠标在xaml中弹出菜单透明背景上丢失了

Dav*_*vid 4 wpf xaml

我今天遇到了一个非常奇怪的问题:

当我将鼠标悬停在图像上方时,我会打开一个弹出菜单.弹出菜单位于图像的右侧.

此弹出菜单模板看起来像一个带有指向图像的小箭头的矩形

菜单包含可点击的元素,所以我需要能够将鼠标从图像移动到菜单而不在它之间关闭,这就是我感到困惑的地方:如果我将鼠标移到箭头尖端然后菜单,一切正常.如果我将鼠标移动到图像和菜单之间的透明空间(箭头上方或下方),菜单将消失.

这是菜单的模板:

<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>
Run Code Online (Sandbox Code Playgroud)

你会注意到我特意把Background =" Transparent "而不是Null(我知道这对hitTesting有什么影响,请看这个问题)

但有趣的是:如果我把Background ="#01000000",它按预期工作.(我几乎得到了我想要的东西,因为这几乎是一个透明的背景)

但我还是想知道那里发生了什么......

我怀疑这与popupmenu这个事实有关.我假设WPF做了一些事情来删除弹出菜单中透明的任何表面上的hitTesting,无论是背景为空(预期)还是特别设置为透明(不是预期的).谁能证实这一点?

Viv*_*Viv 5

将我的评论转换为答案.

这似乎更像是一个"Windows操作系统"问题而不是WPF特别是AllowTransparency="True"在Window级别的方式使得系统在元素上Background="Transparent"Opacity="0"元素上忽略鼠标悬停事件的元素.

可以在此处找到此行为的详细说明

添加MSDN答案以防以后链接丢失:

Windows通过名为"分层窗口"的功能支持HWND级别的透明度.
分层窗口由位图表示.操作系统(OS)在需要时呈现位图.
由于操作系统需要对鼠标移动做出快速响应,因此Windows使用专用的原始输入线程(RIT).RIT在内核中运行并处理来自鼠标硬件的信号.RIT可以扫描HWND层次结构以检测鼠标所在的窗口.对于普通窗口,RIT会根据窗口的矩形检查鼠标位置.对于分层窗口,RIT在位图中查找指定窗口内容的位图,并检查该位置的有效透明度.有效透明度可能受不透明度,颜色和Alpha通道的影响.如果像素是100%透明的,则RIT会跳过窗口并继续查看.这一点是没有触发MouseMove事件的原因.如果窗口和控件的背景都是透明的,在分层窗口中表示此控件(示例中为Canvas)的所有像素都是完全透明的.如上所述,RIT将跳过它们并且永远不会发送WM_MOUSEMOVE消息.因此,如果您只想在鼠标结束时显示控件,否则窗口是透明的,您必须使控件不是100%透明.

在这种情况下需要注意的是,即使PopupWindow没有的情况下AllowTransparency="True",Popup 也会生成一个无Chrome的窗口,弹出窗口AllowTransparency="True"会影响这个新的chromeless-Window,就像上面的MSDN链接中提到的那样.

如果这个控件只是一个标准的控件,比如Button/ Rectangle...那么只需设置Background="Transparent"它就可以使它正常工作而不会出现这个问题.