C# wpf 无边框窗口添加阴影效果的实现

目录
  • 前言
  • 一、如何实现?
    • 1、去除边框
    • 2、添加阴影
    • 3、添加触发器
  • 二、示例代码
  • 三、效果预览
  • 总结

前言

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

一、如何实现?

1、去除边框

(1)方法一

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

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

(2)方法二

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

<Window  WindowStyle="None"  Background="Transparent"  ResizeMode="NoResize">
    <WindowChrome.WindowChrome>
        <WindowChrome GlassFrameThickness="-1"   CaptionHeight="0"   />
    </WindowChrome.WindowChrome
    <Grid>
    </Grid>
</Window>

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>

3、添加触发器

1、 为何添加触发器?

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

2、 具体实现

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

<Grid  Background="#1e1e1e">
    <Grid.Style>
        <Style TargetType="Grid">
            <!--给阴影留出边距-->
            <Style.Triggers>
                <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Normal">
                    <Setter Property="Margin" Value="10" />
                </DataTrigger>
                <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Minimized">
                    <Setter Property="Margin" Value="10" />
                </DataTrigger>
                <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Maximized">
                    <Setter Property="Margin" Value="0" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Style>
</Grid>

二、示例代码

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">
                <!--给阴影留出边距-->
                <Style.Triggers>
                    <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Normal">
                        <Setter Property="Margin" Value="10" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Minimized">
                        <Setter Property="Margin" Value="10" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="Maximized">
                        <Setter Property="Margin" Value="0" />
                    </DataTrigger>
                </Style.Triggers>
            </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>

MainWindow.xaml.cs

using System.Windows;
namespace WpfApp8
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    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();
        }
    }
}

三、效果预览

总结

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

(0)

相关推荐

  • C# WPF 通过委托实现多窗口间的传值的方法

    在使用WPF开发的时候就不免会遇到需要两个窗口间进行传值操作,当然多窗口间传值的方法有很多种,本文介绍的是使用委托实现多窗口间的传值. 在上代码之前呢,先简单介绍一下什么是C#中的委托(如果只想了解如何传值可以略过这部分)在网络上有很多对于委托的介绍和讲解,经过我的学习和总结加上了一点我自己的理解,我认为委托是一种类似于C语言的指针,但是它指向的是方法而不是变量.如果把委托看作一个变量,那么这个变量里存着的就是你目标方法的地址,调用委托约等于调用你的目标方法.(个人理解欢迎指正交流) 以下正文:

  • C# WPF 建立无边框(标题栏)的登录窗口的示例

    前言:笔者最近用c#写WPF做了一个项目,此前未曾做过完整的WPF项目,算是一边学一边用,网上搜了不少资料,效率当然是不敢恭维的,有时会在一些很简单的问题上纠结很长时间,血与泪的教训可不少. 不过,正如电视剧某榜里的一句话:既然我活了下来,就不会白白活着!笔者怎么也算挣扎过了,有些经验与教训可以分享,趁着记忆深刻总结写下来.希望后来者少走弯路,提高工作效率.如果有写得不好的地方,希望读者能够指正,一起进步! --------------------------------- 今天先从登录窗口说起

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

    目录 前言 一.如何实现? 1.去除边框 2.添加阴影 3.添加触发器 二.示例代码 三.效果预览 总结 前言 制作无边框窗口时,系统自带阴影会消失,这时就需要我自己给窗口添加阴影以防止窗口融入背景.添加阴影的方法很简单,直接用effect就可以了,但这里还是有个不容易注意到的细节需要处理,加阴影后窗口最大化可能会有问题. 一.如何实现? 1.去除边框 (1)方法一 使用WindowStyle可以去除窗口边框,AllowsTransparency+Background制造透明窗口为阴影留出透明边

  • vue electron实现无边框窗口示例详解

    目录 一.前言 二.实现方案 1.创建无边框窗口 2.创建windows窗口控件组件 三.后记 一.前言 无边框窗口是不带外壳(包括窗口边框.工具栏等),只含有网页内容的窗口.对于一个产品来讲,桌面应用带边框的很少,因为丑(我们的UI觉得--与我无关-.-).因此我们就来展开说下,在做无边框窗口时候需要注意的事项以及我踩过的坑. 二.实现方案 1.创建无边框窗口 要创建无边框窗口,只需在 BrowserWindow的 options 中将 frame 设置为 false: const { Bro

  • 无边框窗口代码详解

    /*代码思路 此代码会以fullscreen方式打开一个空白窗口,然后用window.resize改变其大小. 最后在以写入onload="location.replace='url'"的办法将网址改变. 打开的窗口会是一个带有FRAME的窗口,其中窗口顶端会有一个高22的框架网页. 此网页是用来操纵窗口移动及关闭. */ /*说明 代码分两个部分,但总共牵涉到5个HTML文件及4个图像文件 第一部分是用来打开窗口,放在哪个文件都无所谓. 第二部分是用来控制窗口的移动及关闭,必须放在指

  • PyQt5实现无边框窗口的标题拖动和窗口缩放

    网上找了半天都找不到好用的PyQt5无边框窗口的实现,借鉴部分前辈的窗口拖放代码,自己实现了一下无边框窗口,问题可能还有一点,慢慢改吧 先做个笔记 py文件 #!/usr/bin/env python #-*- coding:utf-8 -*- from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QVBoxLayout from PyQt5.QtCore import Qt, QPoint from PyQt5.QtGui impo

  • Pyqt实现无边框窗口拖动以及窗口大小改变

    本文实例为大家分享了Pyqt实现无边框窗口拖动及大小改变的具体代码,供大家参考,具体内容如下 做个记录,绘制边框阴影可以忽略这里不是主要 根据网上某位仁兄Qt的实现转过来的大笑,上完整代码 # coding:utf-8 from PyQt4.Qt import * import sys PADDING=4 sys.setrecursionlimit(10000) class ShadowWidget(QWidget): def __init__(self,parent=None): super(

  • Qt透明无边框窗口的实现示例

    最近在封装一些类的时候,打算做一个窗口框架,能实现拖动.无边框.透明基本样式等功能 0x00 如何透明窗口? 第一步:开启窗口的透明层. setWindowFlags(Qt::FramelessWindowHint); /* 注意:如果单纯开启窗口透明层效果,在Windows系统中必须设置, 其他系统可忽略. */ setAttribute(Qt::WA_TranslucentBackground); 第二步: 重写paintEvent事件并使用QPainter画透明层. void paintE

  • Qt无边框窗口拖拽和阴影的实现方法

    无边框窗口的实现 只需要一行代码即可实现 this->setWindowFlags(Qt::FramelessWindowHint); 代码及运行效果: 无边框窗口能拖拽实现 先要去QWidget里面找到 鼠标事件 函数 理一下 坐标的位置 情况: 左上角:屏幕的左上角 中间的窗口:程序的窗口 箭头:鼠标位置 坐标位置满足: x = y - z 在Designer里面拖一个Widget出来叫shadowWidget shadowWidget的颜色为灰色,我们选个自己喜欢的背景色方便查看 接下来我

  • C# 无边框窗体边框阴影效果的简单实现

    通过下面代码在构造函数中调用方法 SetShadow(); 即可实现无边框窗体的阴影效果了 需要添加命名空间 using System.Runtime.InteropServices; 复制代码 代码如下: private const int CS_DropSHADOW = 0x20000;        private const int GCL_STYLE = (-26); [DllImport("user32.dll", CharSet = CharSet.Auto)]     

  • python实现无边框进度条的实例代码

    上python课程时需要设计一个系统,想着为系统加一个启动动画,所以做成了图片加进度条的形式. 本文旨在用python实现无边框的进度条,并在其基础上加了图片,体现了某程序加载动画的效果 实现说明 1.进度条的部分用到了tkinter中的画布组件 2.图片无边框显示用到了PYQT5中的QMainWindow, QApplication (由于水平有限,只好用两个不同的库来实现) 源代码 import sys from PyQt5.QtCore import Qt from PyQt5.QtWid

随机推荐