Dal Raz
Dal Raz

Reputation: 19

WPF: How to Style my form with Transperancy levels

I want to implement this kind of Window:

enter image description here

So currently i have this 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>

Result (ignore the tiger...):

enter image description here

Any idea how to achieve this example Style ?

Update:

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

Result:

enter image description here

Upvotes: 0

Views: 1047

Answers (1)

walterlv
walterlv

Reputation: 2376

You cannot simulate your original image with only GradientBrush, you should blur an image with a large amount of blur radius.


Options to simulate it

It's sad to tell you that you cannot implement the iOS blur style exactly as it shows for you.

But, we have three other methods to simulate this kind of style (on Windows 10) and each has its advantages and disadvantages.

  1. Call the Windows internal API SetWindowCompositionAttribute. You can get a lightly blurred transparent Window but this transparency is much less than the iOS one.
    The image from my post

  2. Add a BlurEffect to the window background image. You can get a more similar visual effect like the iOS one with very poor performance. But in this way, the background image is fixed and cannot be updated when the window moves.
    BlurEffect of WPF

  3. Use UWP instead of WPF and use the AcrylicBrush. You can get a high-performance blur transparent window. But you should try the UWP Application development.
    The UWP AcrylicBrush from learn.microsoft.com


How to implement them

SetWindowCompositionAttribute API

Calling SetWindowCompositionAttribute API is not very easy, so I've written a wrapper class for easier usage. You can use my class by writing only a simple line in the XAML file or in the cs file.

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

Or you can use it in the cs file like this:

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

Just add my wrapper class into your project. It's a very long class so I pasted into GitHub: https://gist.github.com/walterlv/752669f389978440d344941a5fcd5b00.

I also write a post for its usage, but it's not in English: https://walterlv.github.io/post/win10/2017/10/02/wpf-transparent-blur-in-windows-10.html

WPF BlurEffect

Just set the Effect property of a WPF UIElement.

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

Notice that it has a very poor performance.

UWP AcyclicBrush

You can read Microsoft's documents Acrylic material - UWP app developer | Microsoft Docs for more details about how to write an AcylicBrush.

Update

You can add a RectangleGeometry to clip your UIElement into a rounded rectangle.

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>

Upvotes: 2

Related Questions