【问题标题】:WPF Window Blur + Drop shadowWPF 窗口模糊 + 阴影
【发布时间】:2019-01-10 18:40:21
【问题描述】:

我进行了一些搜索,但似乎无法找到一种方法来在我的窗口上使用投影,并使窗口的背景模糊。

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

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

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

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

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

【问题讨论】:

    标签: c# wpf gaussian gaussianblur


    【解决方案1】:

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

    如果是这样,您可以编写 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>
    

    【讨论】:

    • 感谢您的全面回答,但我的意思是让窗口透明并模糊其后面的内容,所以如果我有一个空窗口,并将其放在 Chrome 上打开 Stackoverflow,它会显示网页,但会模糊,而不是模糊窗口内的某些内容。使用我提到的 github 代码可以做到这一点,但是将其与投影相结合会产生问题。
    • @Sef 我有一篇关于窗口模糊效果的帖子。也许您可以先阅读它并确定它是否是您想要的。如果是这样,我会尽快更新这个答案。 walterlv.github.io/post/create-blur-background-window-en.html
    • 我尝试了 CompositionAttribute 方法,因为这是我想做的事情,但它会导致同样的问题。 link 这就是它的样子,模糊延伸到我的 Border 元素之外,它与 Window 有一个小的边距。我需要一种方法来减小应用此模糊的区域的大小,但它仍然需要应用于窗口后面的任何东西,而不是窗口内的控件。感谢您的链接!
    • 因此,使用 DWM 获得高性能的 Windows 本地方法无法实现您的目标。如果您接受在不同系统版本中表现不同的 Windows 原生投影,则可以使用 CompoitionAttribute。否则,唯一的方法是使用我在此答案上发布的方法并使用高 CPU 更新背景图像。
    • @Sef 回复在上面。我忘了@你。
    猜你喜欢
    • 2012-11-02
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 2020-05-06
    相关资源
    最近更新 更多