WPF:如何使用透明度级别设置表单样式

时间:2018-07-10 04:48:41

标签: wpf colors winobjc

我想实现这种Window

enter image description here

所以目前我有这个Style

<Window x:Class="CGTransparent.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="AboutDlg"
    Opacity="0.75"
    ResizeMode="NoResize"
    SizeToContent="WidthAndHeight"
    WindowStartupLocation="CenterScreen"
    WindowStyle="None"
    AllowsTransparency="True" Height="300"
                      Width="500"
    ShowInTaskbar="False"
    Background="#00000000">
    <Window.Resources>
        <LinearGradientBrush x:Key="GradientBrush" StartPoint="0,0" EndPoint="1,1">
            <GradientStop Color="Black" Offset="0.1" />
            <GradientStop Color="#202020" Offset="0.25" />
            <GradientStop Color="#303030" Offset="0.50" />
            <GradientStop Color="#404040" Offset="0.75" />
            <GradientStop Color="#505050" Offset="1.0" />
        </LinearGradientBrush>
    </Window.Resources>
    <Border CornerRadius="15" DockPanel.Dock="Top" Background="{DynamicResource GradientBrush}" Margin="0" Padding="0" BorderBrush="Black" BorderThickness="0">
        <Grid Margin="0" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="500" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="300" />
            </Grid.RowDefinitions>
        </Grid>
    </Border>
</Window>

结果(忽略老虎...):

enter image description here

任何想法如何实现此示例Style吗?

更新

<Window x:Class="app.Forms.Window1"
        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"
        xmlns:local="clr-namespace:PacketPlayer.Forms"
        mc:Ignorable="d"
        WindowStartupLocation="CenterOwner"
        AllowsTransparency="True" WindowStyle="None"
        Title="Window1" Height="300" Width="300">
    <Border BorderBrush="Transparent" BorderThickness="1" CornerRadius="20">
        <Grid>
        <Image Source="C:\Users\racr\Desktop\download.jpg" Stretch="Fill" Margin="-60">
            <Image.Effect>
                <BlurEffect KernelType="Gaussian" Radius="60" />
            </Image.Effect>
        </Image>
        <Border CornerRadius="60" Margin="30" Background="#7F000000">
            <TextBlock Foreground="White"
                       FontSize="20" FontWeight="Light" TextAlignment="Center"
                       HorizontalAlignment="Center" VerticalAlignment="Center">
                <Run Text="Hello World" FontSize="48"/>
                <LineBreak/>
                <Run Text="walterlv.github.io"/>
            </TextBlock>
        </Border>
        </Grid>
    </Border>
</Window>

结果:

enter image description here

1 个答案:

答案 0 :(得分:0)

您不能仅使用GradientBrush模拟原始图像,而应该模糊具有大量模糊半径的图像。


模拟它的选项

这是可悲的告诉你,你的不能实施了iOS模糊风格,正是因为它显示了你。

但是,我们还有其他三种方法来模拟这种样式(在Windows 10上),每种方法都有其优点和缺点。

  1. 调用Windows内部API SetWindowCompositionAttribute。您可以得到一个稍微模糊的透明窗口,但是此透明度比iOS透明窗口要小得多。
    The image from my post

  2. 向窗口背景图像添加BlurEffect。您会获得与iOS类似的视觉效果,但效果非常差。但是通过这种方式,背景图像是固定的,并且在窗口移动时无法更新。
    BlurEffect of WPF

  3. 使用UWP代替WPF并使用AcrylicBrush。您可以获得高性能的模糊透明窗口。但是您应该尝试UWP应用程序开发。
    The UWP AcrylicBrush from docs.microsoft.com


如何实现它们

SetWindowCompositionAttribute API

调用SetWindowCompositionAttribute API并不是一件容易的事,因此我编写了一个包装器类以便于使用。您可以通过仅在XAML文件在cs文件中编写简单行的方式来使用我的课程。

<Window x:Class="CGTransparent.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:interop="clr-namespace:Walterlv.Demo.Interop"
    mc:Ignorable="d" Title="AboutDlg" Height="350" Width="525"
    interop:WindowBlur.IsEnabled="True"
    Background="Transparent">
</Window>

或者您可以像这样在cs文件中使用它:

public class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        WindowBlur.SetIsEnabled(this, true);
    }
}

只需将我的包装器类添加到您的项目中即可。这是一个很长的课程,所以我粘贴到GitHub:https://gist.github.com/walterlv/752669f389978440d344941a5fcd5b00

我还写了一篇关于其用法的帖子,但它不是英文的:https://walterlv.github.io/post/win10/2017/10/02/wpf-transparent-blur-in-windows-10.html

WPF BlurEffect

只需设置WPF UIElement的Effect属性。

<Window x:Class="MejirdrituTeWarqoudear.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        AllowsTransparency="True" WindowStyle="None"
        Width="540" Height="360">
    <Grid>
        <Image Source="YourImageFile.jpg" Stretch="Fill" Margin="-60">
            <Image.Effect>
                <BlurEffect KernelType="Gaussian" Radius="60" />
            </Image.Effect>
        </Image>
        <Border CornerRadius="60" Margin="30" Background="#7F000000">
            <TextBlock Foreground="White"
                       FontSize="20" FontWeight="Light" TextAlignment="Center"
                       HorizontalAlignment="Center" VerticalAlignment="Center">
                <Run Text="Hello World" FontSize="48"/>
                <LineBreak/>
                <Run Text="walterlv.github.io"/>
            </TextBlock>
        </Border>
    </Grid>
</Window>

请注意,它的性能非常差。

UWP AcyclicBrush

您可以阅读Microsoft的文档Acrylic material - UWP app developer | Microsoft Docs,以获取有关如何编写AcylicBrush的更多详细信息。

更新

您可以添加RectangleGeometry来将UIElement裁剪为圆角矩形。

Rounded Rectangle

<Window x:Class="MejirdrituTeWarqoudear.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Width="540" Height="360">
    <Grid>
        <Grid.Clip>
            <RectangleGeometry RadiusX="60" RadiusY="60" Rect="30 30 480 300" />
        </Grid.Clip>
        <Image Source="High+Sierra.jpg" Stretch="Fill" Margin="-60">
            <Image.Effect>
                <BlurEffect KernelType="Gaussian" Radius="60" />
            </Image.Effect>
        </Image>
        <Border Background="#7F000000">
            <TextBlock Foreground="White"
                       FontSize="20" FontWeight="Light" TextAlignment="Center"
                       HorizontalAlignment="Center" VerticalAlignment="Center">
                <Run Text="Hello World" FontSize="48"/>
                <LineBreak/>
                <Run Text="walterlv.github.io"/>
            </TextBlock>
        </Border>
    </Grid>
</Window>