wpf 如何在WPF中创建一个允许鼠标事件通过的半透明窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2842667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a semi transparent window in WPF that allows mouse events to pass through
提问by RMK
I am trying to create an effect similar to the Lights out /lights dim feature in Adobe Lightroom (http://www.youtube.com/watch?v=87hNd3vaENE) except in WPF.
我正在尝试在 Adobe Lightroom ( http://www.youtube.com/watch?v=87hNd3vaENE) 中创建类似于 Lights out /lights dim 功能的效果,但在 WPF 中除外。
What I tried was to create another window over-top of my existing window, make it transparent and put a semi transparent Path geometry on it. But I want mouse events to be able to pass through this semi transparent window (on to windows below).
我尝试的是在现有窗口的顶部创建另一个窗口,使其透明并在其上放置一个半透明的路径几何体。但我希望鼠标事件能够通过这个半透明窗口(到下面的窗口)。
This is a simplified version of what I have:
这是我所拥有的简化版本:
<Window x:Class="LightsOut.MaskWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
AllowsTransparency="True"
WindowStyle="None"
ShowInTaskbar="False"
Topmost="True"
Background="Transparent">
<Grid>
<Button HorizontalAlignment="Left" Height="20" Width="60">click</Button>
<Path IsHitTestVisible="False" Stroke="Black" Fill="Black" Opacity="0.3">
<Path.Data>
<RectangleGeometry Rect="0,0,1000,1000 "/>
</Path.Data>
</Path>
</Grid>
The window is fully transparent, so on places where the Path doesn't cover, mouse events pass right through. So far so good. The IsHitTestvisible is set to false on the path object. So mouse events will pass through it to other controls on the same form (ie you can click on the Button, because it is on the same form).
窗口是完全透明的,因此在 Path 没有覆盖的地方,鼠标事件会直接通过。到现在为止还挺好。路径对象上的 IsHitTestvisible 设置为 false。因此鼠标事件将通过它传递给同一窗体上的其他控件(即您可以单击按钮,因为它在同一窗体上)。
But mouse events wont pass through the Path object onto windows that are below it.
但是鼠标事件不会通过 Path 对象传递到它下面的窗口。
Any ideas? Or better ways to solve this problem?
有任何想法吗?或者更好的方法来解决这个问题?
Thanks.
谢谢。
回答by Oleg Kolosov
I've had similar problem and found a solution:
我遇到了类似的问题并找到了解决方案:
public static class WindowsServices
{
const int WS_EX_TRANSPARENT = 0x00000020;
const int GWL_EXSTYLE = (-20);
[DllImport("user32.dll")]
static extern int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
public static void SetWindowExTransparent(IntPtr hwnd)
{
var extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
}
}
for your window set:
对于您的窗口集:
WindowStyle = None
Topmost = true
AllowsTransparency = true
in code behind for the window add:
在窗口后面的代码中添加:
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
var hwnd = new WindowInteropHelper(this).Handle;
WindowsServices.SetWindowExTransparent(hwnd);
}
and voila - click-through window! See original answer in: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a3cb7db6-5014-430f-a5c2-c9746b077d4f
瞧——点击窗口!请参阅以下原始答案:http: //social.msdn.microsoft.com/Forums/en-US/wpf/thread/a3cb7db6-5014-430f-a5c2-c9746b077d4f
回答by Steven
What you described sounds like the expected behavior. One solution is to set the Fill to {x:Null} on the Path as that is the only sure way to make an object not hit test.
您所描述的听起来像是预期的行为。一种解决方案是将 Path 上的 Fill 设置为 {x:Null},因为这是使对象未命中测试的唯一可靠方法。
回答by AgentFire
I haveanother idea.
我还有一个想法。
What if you made exactly ONE PIXEL, right under the mouse cursor, completely transparent? :]
如果您在鼠标光标正下方制作完全透明的 ONE PIXEL 会怎样?:]