首页 > 解决方案 > WPF 窗口模糊 + 阴影

问题描述

我已经进行了一些搜索,但似乎找不到在窗口上同时使用投影和模糊窗口背景的方法。

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

我尝试使用 OpacityMask,但这似乎没有帮助。事实上,即使将Window的Opacity属性设置为0,仍然会出现模糊,所以我担心这种模糊方法是不可能的。

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

TLDR: 有没有办法同时使用 Aero 风格的模糊窗口和投影?理想情况下不安装额外的软件包,但如果没有其他办法,我将不得不硬着头皮。

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

标签: c#wpfgaussiangaussianblur

解决方案


你的意思是下图的效果吗?

最后的效果

如果是这样,您可以编写 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在它上面设置 a ,它就会被剪裁。我们应该创建另一个形状来渲染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>

推荐阅读