当前位置:网站首页>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。所以阴影只适合对性能要求不高的场景。
边栏推荐
- 中集世联达工业级成熟航运港口人工智能AI产品规模化应用,打造新一代高效能智慧港口和创新数字港口,全球港航人工智能能领军者中集飞瞳
- 分布式消息队列平滑迁移技术实战
- Mongo for infrastructure
- 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
- Linux-安装MySQL(详细教程)
- Hangzhou electric school game 2 1001 2022 Static Query on Tree (Tree + hash table difference chain subdivision
- Kettle--MySQL生产数据库千万、亿级数据量迁移方案及性能优化
- 好未来单季营收2.24亿美元:同比降84% 张邦鑫持股26.3%
- LeetCode Exercise - Two Questions About Finding Sum of Array Elements
- 网络基础(二)-Web服务器-简介——WampServer集成服务器软件之Apache+MySQL软件安装流程 & netstat -an之检测计算机的端口是否占用
猜你喜欢

Graphic LeetCode -- 11. Containers of most water (difficulty: medium)

MySQL data types

Linux-安装MySQL(详细教程)

一文读懂“语言模型”

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

Codeblocks + Widgets create window code analysis

你好,我的新名字叫“铜锁/Tongsuo”

(2022杭电多校四)1001-Link with Bracket Sequence II(区间动态规划)

Network Basics (3) 01-Basic Concepts of Networks - Protocols, Host Addresses, Paths and Parameters of URL Addresses & 127.0.0.1 Local Loopback Address & View URL IP Address and Access Ping Space + URL

Fixed asset visualization intelligent management system
随机推荐
What is industrial radiography equipment?
Quickly build an e-commerce platform based on Amazon cloud technology serverless service - performance
ByteArrayInputStream class source code analysis
国轩高科瑞交所上市:募资近7亿美元 为瑞士今年最大融资项目
ESP8266-Arduino programming example-BMP180 air pressure temperature sensor driver
Presto 中 lookUp Join的实现
单例模式 (Singleton)
BI报表与数据开发
SQL存储过程详解
【HMS Core】【FAQ】运动健康、音频编辑、华为帐号服务 典型问题合集7
Vulkan与OpenGL对比——Vulkan的全新渲染架构
Dodging ice cream assassins?Crawling ice cream prices through crawlers
沉浸式体验科大讯飞2022消博会“官方指定产品”
Hangzhou electric school game 2 1001 2022 Static Query on Tree (Tree + hash table difference chain subdivision
Mysql brush dirty several scenarios and related parameters
One year after graduation, I was engaged in software testing and won 11.5k. I didn't lose face to the post-98 generation...
针不戳,数据库性能优化八大方案。
分布式消息队列平滑迁移技术实战
图解LeetCode——11. 盛最多水的容器(难度:中等)
「Redis应用与深度实践笔记」,深得行业人的心,这还不来看看?