我今天遇到了一个非常奇怪的问题:
当我将鼠标悬停在图像上方时,我会打开一个弹出式菜单。弹出菜单位于图像的右侧。
此弹出菜单模板看起来像一个带有指向图像的小箭头的矩形
菜单包含可点击的元素,所以我需要能够将鼠标从图像移动到菜单而不会在它们之间关闭,这就是我感到困惑的地方:如果我将鼠标移到了尖端的上方箭头然后菜单,一切正常。如果我将鼠标移动到图像和菜单之间的透明空间(箭头上方或下方),则菜单会消失。
以下是菜单的模板:
<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>
你会注意到我特意把Background =“透明”而不是Null(我知道这对hitTesting有影响,请参阅this question)
但有趣的是:如果我把Background =“#01000000”,它按预期工作。 (而且我几乎得到了我想要的东西,因为这几乎是一个透明的背景)但我仍然想知道那里发生了什么......
我怀疑这与弹出菜单这一事实有关。我假设WPF做了一些事情来删除弹出菜单中透明的任何表面上的hitTesting,无论是背景为空(预期)还是特别设置为透明(不是预期的)。谁能证实这一点?
答案 0 :(得分:5)
将我的评论转换为答案。
这似乎更像是一个&#34; Windows操作系统&#34;问题比WPF特别是在窗口级别AllowTransparency="True"
的方式使得系统在元素上Background="Transparent"
或Opacity="0"
时忽略鼠标悬停事件的元素。
可以在 Here
中找到有关此行为的详细说明添加MSDN答案以防以后链接丢失:
Windows通过名为&#34;分层窗口&#34;的功能支持HWND级别的透明度 分层窗口由位图表示。 操作系统(OS)在需要时呈现位图 由于操作系统需要对鼠标移动做出快速响应,因此Windows使用专用的原始输入线程(RIT)。 RIT在内核中运行并处理来自鼠标硬件的信号。 RIT可以扫描HWND层次结构以检测鼠标所在的窗口。 对于普通窗口,RIT会根据窗口的矩形检查鼠标位置。 对于分层窗口,RIT在位图中查找指定窗口内容的位图,并检查该位置的有效透明度。有效透明度可能受不透明度,颜色和Alpha通道的影响。 如果像素是100%透明的,则RIT会跳过窗口并继续查看。这一点是没有触发MouseMove事件的原因。 如果窗口和控件的背景都是透明的,则分层窗口中表示此控件(示例中为Canvas)的所有像素都是完全透明的。如上所述,RIT将跳过它们并且永远不会发送WM_MOUSEMOVE消息。 因此,如果您只想在鼠标结束时显示控件,否则窗口是透明的,您必须使控件不是100%透明。
在这种情况下需要注意的是,即使Popup
在Window
内没有AllowTransparency="True"
,Popup也会生成一个无Chrome浏览器窗口和{{1} Popup影响这个新的chromeless-Window,就像上面MSDN链接中提到的那样。
如果此控件只是AllowTransparency="True"
/ Button
之类的标准控件...那么只需设置Rectangle
就可以使其正常工作而不会出现此问题。