WPF窗口模糊+阴影

时间:2018-08-02 22:31:09

标签: c# wpf gaussian gaussianblur

我已经进行了一些搜索,但是我似乎找不到一种既可以在窗口上使用阴影又可以使窗口背景模糊的方法。

我目前正在使用https://github.com/riverar/sample-win32-acrylicblur(MainWindow.xaml.cs中的所有模糊代码)来模糊背景,但是由于下拉阴影需要在窗口中进行一些填充以渲染下拉阴影,因此下拉阴影的空间也将模糊效果应用到它。

我尝试使用OpacityMask,但这似乎无济于事。实际上,即使将“窗口”的“不透明度”属性设置为0,模糊仍然会显示,因此我担心使用这种模糊方法是不可能的。

我已经在使用的软件包之一是Microsoft.Windows.Shell,我需要重建应用投影后丢失的默认按钮,也许这有帮助。

TLDR: 有没有办法同时使用Aero风格的模糊窗口和阴影?理想情况下,无需安装额外的程序包,但是如果没有其他方法,我将不得不忍辱负重。

我正在使用截至2018年3月8日的.Net等最新版本

1 个答案:

答案 0 :(得分:1)

你的意思是下面显示的效果吗?

The final effect

如果是这样,您可以编写XAML代码来获取它。


<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>

注意:

我写了三个UIElement以实现这种效果:

  1. BlurringShape渲染位图并对其自身进行模糊处理。它在半径32处模糊,因此应设置-32边距,以避免透明模糊。
  2. BackgroundBorder会裁剪BlurringShape,以使模糊不会溢出。
  3. 因为我们已经裁剪了BackgroundBorder,所以如果在其上设置DropShadowEffect,它将被裁剪。我们应该创建另一个形状来渲染DropShadowEffect。那就是ShadowShape

如果您想让样式更具可重用性,可以在下面输入以下代码:

<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>