可在上一篇文章中,介绍了Window类的一些功能,本文继续介绍其它功能。
调整大小模式
可以通过ResizeMode属性,来设置窗口的调整大小模式。它是一个ResizeMode枚举类型,定义如下:
public enum ResizeMode{NoResize, //不能调整大小,“最小化”和“最大化”按钮不会显示在标题栏CanMinimize, //窗口只能最小化/恢复。同时显示“最小化”和“最大化”按钮,但仅启用“最小化”按钮。CanResize, //可以调整大小,并显示“最小化”和“最大化”按钮(默认值)CanResizeWithGrip //可以调整窗口的大小。最小化和最大化按钮同时显示和启用。窗口的右下角将显示一个调整大小的夹点。}
各模的效果如下:
窗口状态
可以通过Window.WindowState属性设置窗口状态当前的状态。它是一个WindowState枚举类型,定义如下:
public enum WindowState{Normal, //正常显示(默认)Minimized, //最小化Maximized //最大化}
例如我们想手动设置窗口最小化,可以使用下面的代码
this.WindowState = WindowState.Minimized;
说明:
1、在最小化或最大化窗口之前,其大小和位置存储在RestoreBounds中。 在随后还原窗口时,其大小和位置值使用RestoreBounds中的值进行还原。
2、更改 WindowState 属性时, Window.StateChanged 事件将被触发 。
创建非矩形的窗口
传统的应用程序基本都是矩形的窗口,对于现在的应用程序开发来说,不再拘泥于传统的窗口展现形式。
例如像桌面美化软件upupoo就采用了圆角矩形的安装包
小鸟壁纸采用了圆形的安装界面
下面介绍如何在WPF中实现非矩形的窗口。
1、设置Window.AllowTransparency属性为true
2、设置Window.WindowStyle属性为None
3、背窗口背景颜色设置为透明,即Window.Background=Transparent
此时我们已经得到了一个全透明的窗口,往窗口上增加不透明的具有所需形状的内容,窗口就会显示为该形状的效果。
这里我们可以添加但不仅限于以下内容:
1、使用支持透明格式的文件提供背景插图,如使用PNG,效果如下图所示。需要注意的是,因为在具有更高DPI的窗口中呈现时需要使用更多的像素,背景图片可能会变得模糊,当允许用户更改窗口大小时,也会出现这一问题。
XAML
<Window x:Class="WindowDemo.PngWindow"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:WindowDemo"mc:Ignorable="d"Title="PngWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent"><Grid><Grid.Background><ImageBrush ImageSource="dd.png" Stretch="Uniform"></ImageBrush></Grid.Background><Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"></Button></Grid></Window>
2、使用形状绘制功能创建具有矢量内容的背景,不管是窗口尺寸改变,还是系统DPI改变,矢量内容都不会失真。
XAML
<Window x:Class="WindowDemo.PathWindow"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:WindowDemo"mc:Ignorable="d"Title="PathWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent"><Grid><Canvas UseLayoutRounding="False" Width="180" Height="180"><Canvas.Clip><RectangleGeometry Rect="0.0,0.0,169.39037,161.76305"/></Canvas.Clip><Path Fill="#ff000000"><Path.Data><PathGeometry Figures="m 163.915 56.9601 l -50.78 -7.38 l -22.7 -46.02 c -0.62 -1.26 -1.64 -2.28 -2.9 -2.9 c -3.16 -1.56 -7 -0.26 -8.58 2.9 l -22.7 46.02 l -50.78 7.38 c -1.4 0.2 -2.68 0.86 -3.66 1.86 c -2.46 2.54 -2.42 6.58 0.12 9.06 l 36.74 35.82 l -8.68 50.58 c -0.24 1.38 -0.02 2.82 0.64 4.06 c 1.64 3.12 5.52 4.34 8.64 2.68 l 45.42 -23.88 l 45.42 23.88 c 1.24 0.66 2.68 0.88 4.06 0.64 c 3.48 -0.6 5.82 -3.9 5.22 -7.38 l -8.68 -50.58 l 36.74 -35.82 c 1 -0.98 1.66 -2.26 1.86 -3.66 c 0.54 -3.5 -1.9 -6.74 -5.4 -7.26 z m -48.66 41.7 l 7.22 42.06 l -37.78 -19.84 l -37.78 19.86 l 7.22 -42.06 l -30.56 -29.8 l 42.24 -6.14 l 18.88 -38.26 l 18.88 38.26 l 42.24 6.14 z" FillRule="Nonzero"/></Path.Data></Path></Canvas><Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"></Button></Grid></Window>
3、使用更简单的具有所有形状的WPF元素,如使用Border可以创建出具有圆角的窗口,使用Ellipse可以创建椭圆窗口。
XAML
<Window x:Class="WindowDemo.IrregularElementWindow"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:WindowDemo"mc:Ignorable="d"Title="IrregularElementWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent"><Grid><Border Width="200" Height="400" BorderThickness="3" BorderBrush="Green" CornerRadius="20"><Border.Effect><DropShadowEffect></DropShadowEffect></Border.Effect></Border><Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"></Button></Grid></Window>
如何移动不规则的窗口
不规则窗口不再具有标题栏,所以无法拖动窗口,幸运的是,系统封装了一个函数可以启动拖动模式。调用Window.DragMove()函数可以对窗口进行拖动
XAML
<Grid Height="30" Background="LightBlue" VerticalAlignment="Top" Margin="0,35" Width="160" MouseDown="Grid_MouseDown"><Label Content="点击我可以拖动窗口"></Label></Grid>
XAML.cs
private void Grid_MouseDown(object sender, MouseButtonEventArgs e){if(e.LeftButton == MouseButtonState.Pressed)this.DragMove();}
如何改变非矩形窗口的尺寸
对于非矩形的窗口,如果窗口的形状大体上还是矩形,或者窗口的内容基本是铺满整个窗口的,我们可以设置Window.ResizeMode为CanResizeWithGrip值为窗口添加一个用于改变窗口大小的手柄。如下所示:
但这种方式并不理想,最好的办法还是捕获鼠标,根据鼠标移动来动态计算窗口的大小。
原理如下:
1、放置一个热点区域,当鼠标进入时,变成可拖动状态。
2、鼠标按下时,捕获鼠标,根据鼠标拖动的大小调整窗口大小
3、鼠标松开时,释放鼠标。
具体实现方法如下:
1、放置一个Rectange/Border元素,设置背景为Transparent,宽度为5个单位,并显示在内容区域右边。
<Window ... Height="450" Width="205" WindowStyle="None" AllowsTransparency="True" Background="Transparent"><Grid><Rectangle Width="5" Height="400" HorizontalAlignment="Right" Fill="Transparent" Cursor="SizeWE"></Rectangle><Border Name="content" Margin="0,0,5,0" Height="400" BorderThickness="3" BorderBrush="Green" CornerRadius="20" Background="White"><Border.Effect><DropShadowEffect></DropShadowEffect></Border.Effect></Border></Grid></Window>
说明:这里只添加了右侧调整大小的手柄,依次添加其它方向即可。
2、为Rectangle/Border添加鼠标按下/松开和移动的事件处理
<Rectangle... MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" MouseLeftButtonUp="Rectangle_MouseLeftButtonUp" MouseMove="Rectangle_MouseMove" />
3、事件处理逻辑如下:
private bool isPressed = false;public IrregularElementWindowWithResize(){InitializeComponent();}private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){isPressed = true;}private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e){isPressed = false;var rect = sender as Rectangle;rect.ReleaseMouseCapture();}private void Rectangle_MouseMove(object sender, MouseEventArgs e){if (isPressed){Rectangle rect = sender as Rectangle;rect.CaptureMouse();var currentPos = e.GetPosition(this.content);double newWidth = currentPos.X + 5;if(newWidth > 0){this.Width = newWidth + 5;}}}
实现效果如下:
其它常用属性
窗口置顶(TopMost)
通过Window.TopMost属性可以设置为窗口是否置顶,当设置TopMost为True时,窗口会置顶显示,不会被其它窗口盖住,即使焦点不在当前窗口。
显示在任务栏(ShowInTaskbar)
通过Window.ShowInTaskBar属性可以设置为窗口是否显示在任务栏,当设置ShowInTaskbar为False时,当前窗口不会显示在任务栏。
根据内容自动调整窗口大小(SizeToContent)
通过Window.SizeToContent属性可以指示窗口是否自动调整自身大小以适应其内容大小。当设置为True时,窗口大小会根据窗口内容自动调整
首次显示是否激活(ShowActivated)
通过Window.ShowActivated属性可以指示在第一次显示窗口时,窗口是否处于激活状态。当设置为False时,窗口在第一次显示时不会激活。
示例代码
https://github.com/zhaotianff/DotNetCoreWPF/tree/master/七、WPF中的常用控件(二)
参考资料
https://learn.microsoft.com/en-us/dotnet/api/system.windows.window

