1

I've done some searching but I can't seem to find a way to use both a drop shadow on my window, and have the window's background blurred.

I'm currently using https://github.com/riverar/sample-win32-acrylicblur (all blur code in MainWindow.xaml.cs) to blur the background, but since the dropshadow requires some padding in the window to render the dropshadow in, the space of the dropshadow gets the blur applied to it too.

I tried using an OpacityMask, but that didn't seem to help. In fact, even when setting the Window's Opacity property to 0, the blur still showed, so I fear that it's not possible with this method of blurring.

One of the packages I already am using is Microsoft.Windows.Shell, which I need to rebuild the default buttons I lose after applying the drop shadow, perhaps this has something helpful.

TLDR: Is there a way to use an Aero-style blurred Window and a drop shadow together? Ideally without installing extra packages, but if there's no other way I'll have to bite the bullet.

I'm on the latest versions of .Net etc. as of 03/08/2018

Sef
  • 101
  • 2
  • 4

1 Answers1

2

Do you mean the effect shown below?

The final effect

If so, you can write the XAML code to get it.


<Window x:Class="Walterlv.Demo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"
        AllowsTransparency="True" WindowStyle="None" Background="{x:Null}">
    <Grid>
        <Rectangle x:Name="ShadowShape" Fill="White" Margin="8">
            <Rectangle.Effect>
                <DropShadowEffect BlurRadius="8" ShadowDepth="0" />
            </Rectangle.Effect>
        </Rectangle>
        <Border x:Name="BackgroundBorder" Margin="8" ClipToBounds="True">
            <Rectangle x:Name="BlurringShape" Margin="-32">
                <Rectangle.Fill>
                    <ImageBrush ImageSource="Sample.jpg"/>
                </Rectangle.Fill>
                <Rectangle.Effect>
                    <BlurEffect KernelType="Gaussian" Radius="32" />
                </Rectangle.Effect>
            </Rectangle>
            <Border.CacheMode>
                <BitmapCache />
            </Border.CacheMode>
        </Border>
    </Grid>
    <Grid>
        <!-- Write your own content here... -->
    </Grid>
</Window>

Notes:

I write three UIElement to implement that effect:

  1. The BlurringShape renders a bitmap and blur itself. It blurs at the radius 32, so it should set a -32 margin to avoid the transparent blur.
  2. The BackgroundBorder clips the BlurringShape so that the blur will not spill over.
  3. Because we have clipped the BackgroundBorder, so if we set a DropShadowEffect on it, it will be clipped. We should create another shape to render the DropShadowEffect. That is the ShadowShape.

If you want your style more reusable, you can take this code below:

<Window x:Class="Walterlv.Demo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
    <Window.Background>
        <ImageBrush ImageSource="High+Sierra.jpg"/>
    </Window.Background>
    <Window.Style>
        <Style TargetType="Window">
            <Setter Property="AllowsTransparency" Value="True" />
            <Setter Property="WindowStyle" Value="None" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Window">
                        <Grid>
                            <Rectangle Fill="White" Margin="8">
                                <Rectangle.Effect>
                                    <DropShadowEffect BlurRadius="8" ShadowDepth="0" />
                                </Rectangle.Effect>
                            </Rectangle>
                            <Border x:Name="BackgroundBorder" Margin="8" ClipToBounds="True">
                                <Rectangle Margin="-32" Fill="{TemplateBinding Background}">
                                    <Rectangle.Effect>
                                        <BlurEffect KernelType="Gaussian" Radius="32" />
                                    </Rectangle.Effect>
                                </Rectangle>
                                <Border.CacheMode>
                                    <BitmapCache />
                                </Border.CacheMode>
                            </Border>
                            <ContentPresenter Margin="8" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Style>
    <Grid>
        <!-- Write your own content here ... -->
    </Grid>
</Window>
walterlv
  • 2,366
  • 13
  • 73
  • Thanks for the comprehensive answer, but what I meant was for the window to be see-through and blur the contents behind it, so if I would have an empty window, and put it on top of Chrome with Stackoverflow open, it would show the webpage, but blurred, as opposed to blurring something inside the window. Doing this is possible with the github code I mentioned, but combining this with a drop shadow is creating the problem. – Sef Aug 03 '18 at 17:36
  • @Sef I have a post talking about the window blurring effect. Maybe you can read it first and determine whether it is your want. If so, I'll update this answer as soon as possible. https://walterlv.github.io/post/create-blur-background-window-en.html – walterlv Aug 03 '18 at 22:08
  • I tried the CompositionAttribute method, since that is the one that does what I am trying to do, but it causes the same issue. [link](https://i.gyazo.com/73e75196d67bf01911d91b50b3e81b08.png) This is what it looks like, the blur extends outside of my Border element, which has a small margin from the Window. I need a way to reduce the size of the area that this blur gets applied to, but it still needs to apply to anything behind the Window, as opposed to Controls inside of the Window. Thanks for the link! – Sef Aug 04 '18 at 23:30
  • So there is no way to achieve your goal in Windows native method which uses DWM to get high performance. If you accept the Windows native drop shadow which behaves differently in different system version, you can use the CompoitionAttribute. Else the only way is to use my method posted on this answer and update the background image using high CPU. – walterlv Aug 04 '18 at 23:37
  • @Sef The reply is above. I forgot to @ you. – walterlv Aug 04 '18 at 23:51