Sef
Sef

Reputation: 91

WPF Window Blur + Drop shadow

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

Upvotes: 0

Views: 2348

Answers (1)

walterlv
walterlv

Reputation: 2376

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>

Upvotes: 1

Related Questions