• C# wpf 无边框窗口添加阴影效果



    前言

    制作无边框窗口时,系统自带阴影会消失,这时就需要我自己给窗口添加阴影以防止窗口融入背景。添加阴影的方法很简单,直接用effect就可以了,但这里还是有个不容易注意到的细节需要处理,加阴影后窗口最大化可能会有问题。


    一、如何实现?

    1、去除边框

    (1)方法一

    使用WindowStyle可以去除窗口边框,AllowsTransparency+Background制造透明窗口为阴影留出透明边距。
    注:此方法较影响窗口渲染性能。

    <Window  WindowStyle="None" AllowsTransparency="True"  Background="Transparent" >
    
    • 1

    (2)方法二

    使用WindowChrome也可以实现无边框窗口,.net4.5之后可以使用此组件。WindowChrome通常不会影响渲染性能。

    <Window  WindowStyle="None"  Background="Transparent"  ResizeMode="NoResize">
        <WindowChrome.WindowChrome>
            <WindowChrome GlassFrameThickness="-1"   CaptionHeight="0"   />
        WindowChrome.WindowChrome   
        >
        Grid>
    Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、添加阴影

    使用DropShadowEffect 加Margin属性即可。添加阴影特效后,需要设置margin给阴影留出边距,否则是看不到阴影的。通常到这一步就结束了,如果窗口需要最大化则继续往下。

    <Window >
        <Grid Margin="10" Background="White">
            <Grid.Effect>
                <DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.8" Color="#AAAAAA"/>
            Grid.Effect>
        Grid>
    Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、添加触发器

    1、 为何添加触发器?

    根据上述2个步骤添加完阴影后,如果将窗口最大化就会发现,Margin依然生效,全屏窗口有一个透明外边距,为了解决这问题所以需要添加触发器。
    在这里插入图片描述

    2、 具体实现

    在style中使用触发器,绑定窗口状态,当最大化时边距设为0,其他情况设为阴影需要的边距。在这里需要注意的是此时Grid不可以设置Margin属性了只能在触发器中设置,因为赋值优先级的原因,在Grid中设置Margin后触发器的赋值会失效。

    <Grid  Background="#1e1e1e">
        <Grid.Style>
            <Style TargetType="Grid">
                
                
                    "{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Normal">
                        "Margin" Value="10" />
                    
                    "{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Minimized">
                        "Margin" Value="10" />
                    
                    "{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Maximized">
                        "Margin" Value="0" />
                    
                
            Style>
        Grid.Style>
    Grid>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    二、示例代码

    MainWindow.xaml

    <Window x:Class="WpfApp8.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"
            xmlns:local="clr-namespace:WpfApp8"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800"
            WindowStyle="None"
            Background="Transparent"
            ResizeMode="NoResize"
            >
        <WindowChrome.WindowChrome>
            <WindowChrome GlassFrameThickness="-1"   CaptionHeight="0"   />
        WindowChrome.WindowChrome>
        <Grid  Background="white">
            <Grid.Effect>
                <DropShadowEffect ShadowDepth="0" BlurRadius="10" Opacity="0.8" Color="#AAAAAA"/>
            Grid.Effect>
            <Grid.Style>
                <Style TargetType="Grid">
                    
                    
                        "{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Normal">
                            "Margin" Value="10" />
                        
                        "{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Minimized">
                            "Margin" Value="10" />
                        
                        "{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Maximized">
                            "Margin" Value="0" />
                        
                    
                Style>
            Grid.Style>
            
            <Grid  VerticalAlignment="Top"  >
                <StackPanel Margin="0,0,10,0" HorizontalAlignment="Right" Orientation="Horizontal">
                    
                    <Button Width="50" Height="50" Focusable="False" VerticalAlignment="Center" Cursor="Hand"  Click="Button_Click_1" >
                        <Button.Template>
                            <ControlTemplate TargetType="Button">
                                <Grid x:Name="grd" Background="Transparent">
                                    <Rectangle Width="20" Height="3" Fill="#1e1e1e" >Rectangle>
                                Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="grd" Property="Background" Value="#666666">Setter>
                                    Trigger>
                                ControlTemplate.Triggers>
                            ControlTemplate>
                        Button.Template>
                    Button>
                    
                    <Button Width="50" Height="50" Focusable="False" VerticalAlignment="Center" Cursor="Hand"  Visibility="{DynamicResource MaximizeButtonVisibility}" Click="Button_Click">
                        <Button.Template>
                            <ControlTemplate>
                                <Grid x:Name="grd" Background="Transparent">
                                    <Rectangle Width="20" Height="20" Stroke="#1e1e1e"  StrokeThickness="3">Rectangle>
                                Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="grd" Property="Background" Value="#666666">Setter>
                                    Trigger>
                                ControlTemplate.Triggers>
                            ControlTemplate>
                        Button.Template>
                    Button>
                    
                    <Button Width="50" Height="50"  Focusable="False"  VerticalAlignment="Center" Cursor="Hand" Click="Button_Click_2">
                        <Button.Template>
                            <ControlTemplate>
    
                                <Grid x:Name="grd" Background="Transparent">
                                    <Line Width="20" Height="20" X1="0" Y1="0" X2="20" Y2="20" StrokeThickness="3" Stroke="#1e1e1e" >Line>
                                    <Line Width="20" Height="20" X1="20" Y1="0" X2="0" Y2="20" StrokeThickness="3" Stroke="#1e1e1e" >Line>
                                Grid>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="grd" Property="Background" Value="#666666">Setter>
                                    Trigger>
                                ControlTemplate.Triggers>
                            ControlTemplate>
                        Button.Template>
                    Button>
                StackPanel>
            Grid>
        Grid>
    Window>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    MainWindow.xaml.cs

    using System.Windows;
    namespace WpfApp8
    {
        /// 
        /// Interaction logic for MainWindow.xaml
        /// 
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
            private void Button_Click(object sender, RoutedEventArgs e)
            {        
                WindowState = WindowState== WindowState.Maximized? WindowState .Normal: WindowState.Maximized;
            }
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                WindowState = WindowState.Minimized;
            }
            private void Button_Click_2(object sender, RoutedEventArgs e)
            {
                Close();
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    三、效果预览

    在这里插入图片描述


    总结

    以上就是今天要讲的内容,给窗口添加阴影的方法还是比较简单的,只是需要注意窗口最大化的情况。但实际上窗口阴影对性能影响还是比较大的,尤其是有渲染视频的情况下,消耗更多的cpu。所以阴影只适合对性能要求不高的场景。

  • 相关阅读:
    第2-2-2章 常见组件与中台化-常用组件服务介绍-通用权限系统
    VIRTIO-BLK代码分析(2)VIRTIO驱动分析
    redis-Modules(TairHash)
    代码随想录算法训练营第六天|字符串 & 栈 & 队列
    卫生纸标准及鉴别
    Android 反编译Apk (Mac)
    ubuntu系统 kubeadm方式搭建k8s集群
    2023年武汉市新能源企业产业奖补申报,奖励补贴政策以及申报条件汇总!
    LeetCode-503-下一个更大元素Ⅱ
    `Promise`全面解析
  • 原文地址:https://blog.csdn.net/u013113678/article/details/126045002