I am trying to create an effect similar to the Lights out /lights dim feature in Adobe Lightroom except in 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 the 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 (i.e. you can click on the Button
, because it is on the same form).
But mouse events won't pass through the Path object onto windows that are below it.
Any ideas? Or better ways to solve this problem?
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