WPF Achieve a Danger Reminder Effect

WPF Achieve a Danger Reminder Effect

When our program is released and users are performing dangerous operations, our software should provide some reminder effects, such as a red border edge, similar to the warning effect in Amap.

Last updated 5/27/2025 9:41 PM
就叫我啊禾斗吧 禾斗学编程
5 min read
Category
.NET
Tags
.NET C# WPF

Requirement Background

When our program is distributed and users are performing dangerous operations, our software should provide warning effects, such as red border edges, similar to the alarm warning effect in Amap (Gaode Maps).

Image

Implementation Logic

Prepare a Border element with a border, set its border thickness, border color, and Effect property. The Effect is set to DropShadowEffect, where the key properties are BlurRadius and Color.

Challenge

If the border color is transparent, setting DropShadowEffect will not take effect.

Solution

Set the border color to any opaque color, preferably a solid color. Then use the Grid's ClipToBounds property to clip the excess border of the Border. At this point, you will notice the border line is very thick, which is not ideal. You can think in reverse: set the Border's Margin to a negative value. For example, if BorderThickness is 10, set Margin to -10. Then you will see the desired effect.

Image

<Grid CacheMode="BitmapCache" ClipToBounds="True">     
    <Border Margin="-10" 
            BorderBrush="#FFFF"        
            BorderThickness="10"        
            CacheMode="BitmapCache">        
        <Border.Effect>            
            <DropShadowEffect                
                BlurRadius="40"
                Direction="275"
                RenderingBias="Performance"
                ShadowDepth="0"
                Color="Red" />
        </Border.Effect>
    </Border>
    <Border
            Margin="-10"
            BorderBrush="#FFFF"
            BorderThickness="10"
            CacheMode="BitmapCache">
        <Border.Effect>
            <DropShadowEffect
                 BlurRadius="40"
                 Direction="275"
                 RenderingBias="Performance"
                 ShadowDepth="0"
                 Color="Red" />
        </Border.Effect>    
    </Border>
</Grid>

If the color is too light, you can simply overlay multiple borders.

Reminder: Be sure to read and understand the article carefully before using it. Try not to copy and paste. Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime. Please be patient and understand thoroughly!!!

The site owner implemented an Avalonia version based on the original author's code. The effect is as follows:

The code is as follows:

<u:UrsaWindow xmlns="https://github.com/avaloniaui"
        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:u="https://irihi.tech/ursa"
        mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="450"
        Width="400" Height="450"
        x:Class="DeviceMrgSample.Views.WarningWindow"
        Title="WarningWindow">
	<u:UrsaWindow.Styles>
        <Style Selector="Border.warning-border">
            <Style.Animations>
                <Animation Duration="0:0:05" 
                           IterationCount="Infinite"
                           PlaybackDirection="Alternate">
                    <KeyFrame Cue="0%">
                        <Setter Property="Opacity" Value="0.5"/>
                    </KeyFrame>
                    <KeyFrame Cue="100%">
                        <Setter Property="Opacity" Value="1"/>
                    </KeyFrame>
                </Animation>
            </Style.Animations>
        </Style>
        <Style Selector="Grid#gridRoot > TranslateTransform">
            <Style.Animations>
                <Animation Duration="0:0:0.3" 
                          IterationCount="Infinite">
                    <KeyFrame Cue="0%">
                        <Setter Property="X" Value="0"/>
                        <Setter Property="Y" Value="0"/>
                    </KeyFrame>
                    <KeyFrame Cue="20%">
                        <Setter Property="X" Value="-10"/>
                        <Setter Property="Y" Value="5"/>
                    </KeyFrame>
                    <KeyFrame Cue="40%">
                        <Setter Property="X" Value="8"/>
                        <Setter Property="Y" Value="-7"/>
                    </KeyFrame>
                    <KeyFrame Cue="60%">
                        <Setter Property="X" Value="-12"/>
                        <Setter Property="Y" Value="3"/>
                    </KeyFrame>
                    <KeyFrame Cue="80%">
                        <Setter Property="X" Value="9"/>
                        <Setter Property="Y" Value="-4"/>
                    </KeyFrame>
                    <KeyFrame Cue="100%">
                        <Setter Property="X" Value="0"/>
                        <Setter Property="Y" Value="0"/>
                    </KeyFrame>
                </Animation>
            </Style.Animations>
        </Style>
    </u:UrsaWindow.Styles>

    <Grid x:Name="gridRoot" ClipToBounds="True">
        <Grid.RenderTransform>
            <TranslateTransform/>
        </Grid.RenderTransform>
        
        <Border Classes="warning-border"
                Margin="-25" 
                BorderBrush="#FFFF"
                BorderThickness="25">
            <Border.Effect>
                <DropShadowEffect
                    BlurRadius="40"
                    OffsetX="0"
                    OffsetY="0"
                    Opacity="0.8"
                    Color="Red" />
            </Border.Effect>
        </Border>
        <Border
            Margin="-15"
            BorderBrush="#FFFF"
            BorderThickness="15">
            <Border.Effect>
				<DropShadowEffect
                    BlurRadius="40"
                    OffsetX="0"
                    OffsetY="0"
                    Color="Red" />
            </Border.Effect>
        </Border>
        
        <StackPanel VerticalAlignment="Center" 
                    HorizontalAlignment="Center"
                    Margin="40">
            <TextBlock Text="❗ Disk Alarm ❗" 
                       FontSize="36"
                       FontWeight="Black"
                       Foreground="#FFFF00"
                       Margin="0 0 0 30"
                       TextAlignment="Center">
                <TextBlock.Effect>
                    <DropShadowEffect Color="#CC0000" 
                                    BlurRadius="12" 
                                    OffsetX="2" 
                                    OffsetY="2"/>
                </TextBlock.Effect>
            </TextBlock>
            
            <TextBlock Text="Drive D has less than 2GB free (20%)"
                       FontSize="26"
                       FontWeight="Bold"
                       Foreground="#FFEB3B"
                       TextWrapping="Wrap"
                       MaxWidth="280"
                       Margin="0 0 0 20"
                       TextAlignment="Center">
                <TextBlock.Effect>
                    <DropShadowEffect Color="#B71C1C" 
                                    BlurRadius="8" 
                                    OffsetX="1" 
                                    OffsetY="1"/>
                </TextBlock.Effect>
            </TextBlock>
            
            <TextBlock Text="Clean up immediately to avoid system crash!"
                       FontSize="24"
                       FontWeight="SemiBold"
                       Foreground="#FFEE58"
                       TextAlignment="Center"
                       Margin="0 10 0 0">
                <TextBlock.Effect>
                    <DropShadowEffect Color="#C62828" 
                                    BlurRadius="6" 
                                    OffsetX="1" 
                                    OffsetY="1"/>
                </TextBlock.Effect>
            </TextBlock>
        </StackPanel>
    </Grid>
</u:UrsaWindow>
Keep Exploring

Related Reading

More Articles
Same category / Same tag 6/20/2024

CodeWF.EventBus: Lightweight Event Bus for Smoother Communication

CodeWF.EventBus is a flexible event bus library that enables decoupled communication between modules. It supports various .NET project types such as WPF, WinForms, ASP.NET Core, etc. With a clean design, it easily implements command publishing and subscribing, as well as requests and responses. Through orderly event handling, it ensures events are properly processed. Simplify your code and improve system maintainability.

Continue Reading