当前位置:网站首页>C# wpf 无边框窗口添加阴影效果
C# wpf 无边框窗口添加阴影效果
2022-07-30 18:23:00 【CodeOfCC】
前言
制作无边框窗口时,系统自带阴影会消失,这时就需要我自己给窗口添加阴影以防止窗口融入背景。添加阴影的方法很简单,直接用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。所以阴影只适合对性能要求不高的场景。
边栏推荐
- BI报表与数据开发
- LayaBox---TypeScript---基础数据类型
- 高性能短链设计
- LayaBox---TypeScript---变量声明
- 网络基础(三)01-网络的基础概念——URL地址组成之协议、主机地址、路径和参数&127.0.0.1本地回环地址& 查看网址IP地址并访问之ping空格+网址&netstat -anb查看本机占用端口
- ByteArrayInputStream class source code analysis
- 分布式消息队列平滑迁移技术实战
- Informatics Olympiad All-in-One 1966: [14NOIP Popularization Group] Scale Simplification | Luogu P2118 [NOIP2014 Popularization Group] Scale Simplification
- Hello, my new name is "Bronze Lock/Tongsuo"
- 载誉而归,重磅发布!润和软件亮相2022开放原子全球开源峰会
猜你喜欢

Meta元宇宙部门第二季度亏损28亿!仍要继续押注?元宇宙发展尚未看到出路!

Hangzhou electric school game 2 1001 2022 Static Query on Tree (Tree + hash table difference chain subdivision

linux 安装mysql8.0 超详细教程(实战多次)

A senior with 13 years of experience in software testing, summed up 5 test employment suggestions....

ESP8266-Arduino programming example-BMP180 air pressure temperature sensor driver

网络基础(三)01-网络的基础概念——URL地址组成之协议、主机地址、路径和参数&127.0.0.1本地回环地址& 查看网址IP地址并访问之ping空格+网址&netstat -anb查看本机占用端口

LeetCode 练习——关于查找数组元素之和的两道题

Mongo for infrastructure

MySQL数据类型

国轩高科瑞交所上市:募资近7亿美元 为瑞士今年最大融资项目
随机推荐
DevEco Studio3.0下载失败,提示An unknown error occurred
分布式消息队列平滑迁移技术实战
This year..I sincerely recommend the professional engineer to upgrade to the book!
Mysql brush dirty several scenarios and related parameters
What is an ultrasonic flaw detector used for?
积性函数
[OC study notes] attribute keyword
Basic knowledge points in js - BOM
荐号 | 对你有恩的人,不要请吃饭来报答
攻防世界web-Cat
Application of time series database in the field of ship risk management
Informatics Olympiad 1915: [01NOIP Popularization Group] Greatest Common Divisor and Least Common Multiple | Luogu P1029 [NOIP2001 Popularization Group] The problem of the greatest common divisor and
What are the applications of X-rays?
EMC VPLEX VS2 SPS电池更换详细探讨
单例模式 (Singleton)
沉浸式体验科大讯飞2022消博会“官方指定产品”
SQL存储过程详解
while,do while,for循环语句
深化校企合作 搭建技术技能人才成长“立交桥”
CCNA-NAT协议(理论与实验练习)