WPF中的Window类

news2024/11/28 13:32:42

控件分类

在第一篇文章.Net Core和WPF介绍中的WPF的功能和特性部分根据功能性介绍了WPF的控件 名称。

在接下来的文章中,将会详细的介绍各个控件的概念及使用。

主要包括:

内容控件:Label、Button、CheckBox、ToggleButton、RadioButton、ToolTip和ScrollViewer

带有标题的内容控件:TabItem、GroupBox、Expander

导航控件:Frame、TabControl、Page

窗体控件:Window

文本控件:TextBox、PasswordBox、RichTextBox

列表控件:ListBox和ComboBox

基于范围的控件:Slider和ProgressBar

日期控件:Calender和DatePicker

媒体控件:Image和MediaElement

Window类

Window类继承自ContentControl类,也是内容控件的一种。在上一篇文章中,已经介绍过内容控件。

Window类比较特殊,它跟常规的内容控件不一样。除了额外的属性之外,它还是程序最顶级的元素。可以理解为Window类是WPF程序的最大的容器。所有的控件都是放置在Window类下。

在后面的文章中,会介绍到Application类。每个运行的程序,都由System.Windows.Application类的一个实例来表示。

Application类有一个Run函数,需要传入一个Window对象(或者通过StartupUri属性指定窗体,再调用无参Run函数)。通过调用Run函数,来启动整个WPF应用程序,并打开指定窗体。

常用属性

属性说明
Width指定Window宽度 
Height指定Window高度
WindowStyle

使用WindowStyle枚举值, 设置窗体的边框类型。SingleBorderWindow(默认值)、

None(无边框,只显示内容区域,标题栏和边框都不显示)、

ToolWindow(固定工具窗口)、

ThreeDBorderWindow(具有三维边框的窗口)

AllowTransparency

是否允许透明标志,默认false。

当设置为true,且背景被设置为透明色,整个窗体就会透明。

如果背景设置为透明色,AllowTransparency=false,就会显示黑色背景。

注意:AllowTransparency=true需要和WindowStyle=None配合使用,否则会报错。

这是因为边框不支持透明,只有无边框时,使用AllowTransparency=true才能生效。

 Icon指定窗口图标
 Left和Top使用设备无关像素设置窗口左上角到屏幕左部边缘及顶部之间的距离       
ResizeMode

获取或设置调整大小模式,使用ResizeMode枚举值。

CanMinimize 只能最小化和还原窗口。

同时显示“最小化”和“最大化”按钮,但只有“最小化”按钮处于启用状态。

CanResize 可以调整窗口的大小。

同时显示“最小化”和“最大化”按钮,并且两个按钮均处于启用状态。

CanResizeWithGrip 可以调整窗口的大小。

同时显示“最小化”和“最大化”按钮,并且两个按钮均处于启用状态。

窗口的右下角显示一个大小调整手柄。

NoResize 无法调整窗口的大小。 标题栏中不显示“最小化”和“最大化”按钮。

RestoreBounds获取窗体在最小化或最大化前的位置和大小
ShowInTaskbar运行后是否显示在任务栏,默认是true。
SizeToContent

获取或设置一个值,该值指示窗口是否自动调整自身大小以适应其内容大小,使用SizeToContent枚举值。

Height 指定窗口将自动设置其高度以适合其内容的高度,而非宽度

Manual 指定窗口将如何自动设置其大小以适合其内容大小。

此外,窗口大小还可以由其他属性确定,

其中包括 Width、Height、MaxWidth、MaxHeight、MinWidth 和 MinHeight

Width 指定窗口将自动设置其宽度以适合其内容的宽度,而非高度

WidthAndHeight 指定窗口将自动设置其宽度和高度以适合其内容的宽度和高度

 IsActive获取一个值,该值指示窗口是否为活动窗口。 
 Owner获取或设置当前窗口的拥有者。
 ShowActivated获取或设置一个值,该值指示在第一次显示窗口时,窗口是否处于激活状态。 
 TaskbarItemInfo获取或设置任务栏缩略图。在后面的文章中会详细介绍该功能
 Title获取或设置窗口的标题。 
 TopMost

获取或设置一个值,该值指示窗口是否出现在 Z 顺序的最顶层。

当设置该属性为true时,窗口显示在应用程序其它窗口的上面。即最顶层

WindowsStartupLocation

获取或设置窗口首次显示时的位置。使用WindowsStartupLocation枚举值。

CenterOwner Window 的启动位置位于包含它的 Window 的中央,由 Owner 属性指定。

CenterScreen Window 的启动位置位于包含鼠标光标的屏幕的中央。

Manual 可从代码中设置 Window 的启动位置,或者使用默认的 Windows 位置。

 WindowState

获取或设置一个值,该值指示窗口是处于还原、最小化还是最大化状态。

使用WindowState枚举值 

Maximized 最大化窗口

Minimized 最小化窗口

Normal 还原窗口

DialogResult

获取或设置对话框结果值,此值是从 ShowDialog() 方法返回的值。

窗口组成

WPF窗口由两个不同的区域组成:

  • 非工作区,用于托管窗口装饰,包括图标、标题、系统菜单、最小化按钮、最大化按钮、还原按钮、关闭按钮和边框。

  • 一个工作区,用于托管特定于应用程序的内容。

下图显示了一个标准窗口:

显示窗口

显示窗口主要是调用Window类的Show()函数和ShowDialog()函数。

在程序启动时,WPF内部调用了MainWindow的Show函数。

当我们需要显示新的窗口时,可以有以下两种做法

1、使用Visual Studio 添加一个窗口

在XAML中对窗口进行布局

 1 <Window x:Class="WindowDemo.XAMLWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WindowDemo"
 7         mc:Ignorable="d"
 8         Title="XAMLWindow" Height="450" Width="800">
 9     <Grid>
10         
11     </Grid>
12 </Window>

显示窗体

1 XAMLWindow xAMLWindow = new XAMLWindow();
2 xAMLWindow.ShowDialog();

1 XAMLWindow xAMLWindow = new XAMLWindow();
2 xAMLWindow.Show();

2、直接使用代码创建窗口并显示

 1 Window window = new Window();
 2 window.Width = 720;
 3 window.Height = 500;
 4 window.Background = Brushes.LightSkyBlue;
 5 window.Title = "Window 1";
 6 
 7 Grid grid = new Grid();
 8 
 9 Label label = new Label();
10 label.HorizontalAlignment = HorizontalAlignment.Center;
11 label.VerticalAlignment = VerticalAlignment.Center;
12 label.Content = "Hello World";
13 label.FontSize = 30;
14 grid.Children.Add(label);
15 
16 window.Content = grid;
17 
18 window.ShowDialog();

Show()和ShowDialog的区别

Show():显示非模态窗口,非模态窗口不会阻止用户访问其它任何窗口。调用Show()函数,函数会立即返回。

ShowDialog():显示模态窗口(Modal),模态窗口会通过一种类似强制置顶的模式,锁住所有鼠标和键盘输入来阻止用户访问父窗口,直到模态窗口被关闭。在关闭模态窗口前,ShowDialog()函数也不会返回,这也就意味着后面的代码会被阻塞。

说明:

ShowDialog()函数会返回一个bool?值,代表Dialog的活动是被接受 (true) 还是被取消 (false)。 返回值是 DialogResult 属性在窗口关闭前具有的值。 

像我们平常在调用各种对话框时,都会通过返回值来判断是否执行成功,如文件打开对话框

1 OpenFileDialog openFileDialog = new OpenFileDialog();
2 
3 if(openFileDialog.ShowDialog() == true)
4 {
5     //操作选中的文件
6 }

我们在自己设计一个对话框时,可以通过DialogResult属性来设置对话框的返回值,不管设置哪个值,对话框都会立即关闭并返回。

我们可以创建一个简单的窗口来试验一下

界面XAML

1  <Grid>
2      <Button Content="DialogResult = true" HorizontalAlignment="Center" VerticalAlignment="Top" IsDefault="True" Click="Button_Click"></Button>
3      <Button Content="DialogResult = false" HorizontalAlignment="Center" VerticalAlignment="Bottom" IsCancel="True" Click="Button_Click_1"></Button>
4  </Grid>

后台代码

1  private void Button_Click(object sender, RoutedEventArgs e)
2  {
3      this.DialogResult = true;
4  }
5 
6  private void Button_Click_1(object sender, RoutedEventArgs e)
7  {
8      this.DialogResult = false;
9  }

运行效果

 

关闭窗口

使用Close()函数可以关闭窗口。

如果我们只是想隐藏窗口,可以调用Hide()函数或设置Visibility属性为Hidden。不管使用哪种方式隐蔽窗口,代码依然会在后台执行。

有时候我们想在用户单击关闭按钮后,隐藏窗口,而不关闭窗口,可以在窗口的Closing事件中添加如下代码:

1   private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
2   {
3       e.Cancel = true;
4       //隐藏窗口、最小化窗口、创建托盘图标或其它操作
5   }

像平常使用的微信软件就是在关闭后执行隐藏操作,而不是真正的退出。

窗口启动位置

可以通过设置Window.WindowStartupLocation属性指定第一次打开窗口时所要显示到的位置。 

它的取值是WindowStartupLocation枚举类型,定义如下:

1 public enum WindowStartupLocation
2 {
3     Manual,                 //手动设置第一次启动位置
4     CenterScreen,           //屏幕中央
5     CenterOwner             //拥有者窗口中央
6 }

Manual

窗口第一次启动时,显示在用户指定的位置。

当设置为Manual时,可以通过Window.Left属性和Window.Top属性来设置具体的启动位置。

Window.Left:窗口左边缘相对于桌面的位置

Window.Top:窗口上边缘相对于桌面的位置

如设置Left为80,Top为100,则启动位置如下图所示:

CenterScreen

窗口第一次启动时,显示在屏幕中央位置。

注意:这是第一次启动时的位置,在启动后,仍然可以通过Window.Left和Window.Top属性来修改窗口的位置

CenterOwner

窗口第一次启动时,显示在拥有者窗口的中央。

当设置为CenterOwner时,需要指定窗口的拥有者窗口

如下所示:

1 XAMLWindow xAMLWindow = new XAMLWindow();
2 //设置XAMLWindow的拥有者为当前窗口
3 xAMLWindow.Owner = this; 
4 //XAMLWindow的启动位置设置为当前窗口的中央
5 xAMLWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; 
6 xAMLWindow.Show();

定位窗口

通过Width和Height属性,可以指定窗口的宽度和高度。

通过Left和Top属性,可以控制窗口距离屏幕边缘的位置。

有时候我们需要控制窗口的尺寸和位置,例如当窗口的大小会超过当前屏幕的分辨率的时候。

WPF提供了一个System.Window.SystemParamters类,SystemParamters类里面定义了大量的静态属性,可以用来快速查询系统设置,如屏幕大小、鼠标参数、键盘参数等。

如果我们想获取不带任务栏的屏幕大小,可以通过下面的方式

1 var width = SystemParameters.FullPrimaryScreenWidth;
2 var height = SystemParameters.FullPrimaryScreenHeight;

如果我们想获取整个屏幕(主屏幕)的大小,可以通过下面的方式

1 var width = SystemParameters.PrimaryScreenWidth;
2 var height = SystemParameters.PrimaryScreenHeight;

如果有多个显示器,想获取副屏(其它屏幕)的大小,可以通过下面的方式

1   //多个屏幕时
2   System.Windows.Forms.Screen[] allScreen = System.Windows.Forms.Screen.AllScreens;
3 
4   //屏幕1的工作区域
5   var firstScreenWorkingArea = allScreen[0].WorkingArea;
6   var width = firstScreenWorkingArea.Width;
7   var height = firstScreenWorkingArea.Height;

说明:

如果我们在窗口显示之后再去设置窗口的大小或位置,视觉效果上会看到窗口的改变。

窗口位置

针对窗口位置,可以在调用Show()或者ShowDialog()函数之前设置。

窗口大小

如果窗口的大小是已知且固定的,可以在调用Show()或者ShowDialog()函数之前设置。

如果窗口的大小是动态的,可以在窗口的Loaded事件处理函数中设置。

保存/还原窗口位置和大小

有时候我们需要记录窗口关闭前的位置和大小,以便下次启动时,恢复窗口原来的大小及位置。

我们可以在关闭时,将窗口的Left、Top、Width和Height属性值记录下来,保存到配置文件中。

在启动时,读取配置文件,将窗口恢复到原来的大小和位置。

在日常开发中,需要保存的参数可能远不止窗口位置和大小,如字体大小,界面参数等等,我们都可以用这种方式实现。

WPF提供了一套默认的应用程序设置,可以很方便的保存/读取设置。

说明:

这种方式是保存在资源文件中,无法通过记事本等文本编辑器直接编辑,正式项目推荐使用以XML/Json外部文件的形式保存。

使用默认应用程序设置的方法

1、打开项目的属性页,切换到设置选项卡

 2、点击创建或打开应用程序设置,在这里我们可以添加不同类型的设置项。

添加一个System.Drawing.Size类型的值,用于记录窗口大小;

添加一个System.Drawing.Point类型的值,用于记录窗口的位置。

如下所示

3、在代码中使用设置项

关闭时

1 //使用RestoreBounds属性获取窗口在最小化或最大化之前的大小和位置
2 var restoreBounds = this.RestoreBounds;
3 
4 Properties.Settings.Default.WindowPos = new System.Drawing.Point() { X = (int)restoreBounds.X, Y = (int)restoreBounds.Y };
5 Properties.Settings.Default.WindowSize = new System.Drawing.Size() { Width = (int)restoreBounds.Width, Height = (int)restoreBounds.Height };
6 
7 //保存
8 Properties.Settings.Default.Save();

启动时

1 var winSize = Properties.Settings.Default.WindowSize;
2 var winPos = Properties.Settings.Default.WindowPos;
3 if (winSize.Width != 0 && winSize.Height != 0)
4 {
5     this.Left = winPos.X;
6     this.Top = winPos.Y;
7     this.Width = winSize.Width;
8     this.Height = winSize.Height;
9 }

运行效果

窗口的图标

通过Icon属性可以指定窗口的图标,它可以是来自外部文件、嵌入的资源,也可以是自己绘制的图像。

1、嵌入的资源 

1 1 <Window ...
2 2         Icon="logo.jpg">
3 3 </Window>

2、外部文件

1 1 <Window ...
2 2         Icon="D:\logo.jpg">
3 3 </Window>

3、绘制的图像

1 <Window.Icon>
2     <DrawingImage>
3         <DrawingImage.Drawing>
4              ...
5         </DrawingImage.Drawing>
6     </DrawingImage>
7 </Window.Icon>

窗口的边框样式

可以通过Window.WindowStyle属性设置窗口的边框样式,它是一个WindowStyle枚举类型,定义如下:

1 public enum WindowStyle
2 {  
3     None,                         //无
4     SingleBorderWindow,           //单边框(默认值)
5     ThreeDBorderWindow,           //3-d 边框
6     ToolWindow                    //固定的工具窗口
7  }

各样式的显示效果如下:

说明:

1、当设置窗口允许透明,即AllowTransparency=true时,WindowStyle要设置为None,因为边框不支持透明,否则会报错。

2、Windows 10/11 22H2之前的版本可以通过Win32 API 函数SetWindowCompositionAttribute()设置带边框的窗口支持毛玻璃透明效果。如下所示

3、在后面创建不规则窗口时,也需要设置为WindowStyleNone

调整大小模式

可以通过ResizeMode属性,来设置窗口的调整大小模式。它是一个ResizeMode枚举类型,定义如下:

1 public enum ResizeMode
2 {
3     NoResize,         //不能调整大小,“最小化”和“最大化”按钮不会显示在标题栏
4     CanMinimize,      //窗口只能最小化/恢复。同时显示“最小化”和“最大化”按钮,但仅启用“最小化”按钮。
5     CanResize,        //可以调整大小,并显示“最小化”和“最大化”按钮(默认值)
6     CanResizeWithGrip //可以调整窗口的大小。最小化和最大化按钮同时显示和启用。窗口的右下角将显示一个调整大小的夹点。
7 }

 各模式的效果如下:

窗口状态

可以通过Window.WindowState属性设置窗口状态当前的状态。它是一个WindowState枚举类型,定义如下:

1 public enum WindowState
2 {  
3     Normal,                  //正常显示(默认)
4     Minimized,               //最小化
5     Maximized                //最大化
6 }

例如我们想手动设置窗口最小化,可以使用下面的代码

1   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

 1 <Window x:Class="WindowDemo.PngWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WindowDemo"
 7         mc:Ignorable="d"
 8         Title="PngWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
 9     <Grid>
10         <Grid.Background>
11             <ImageBrush ImageSource="dd.png" Stretch="Uniform"></ImageBrush>
12         </Grid.Background>
13 
14         <Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"></Button>
15     </Grid>
16 </Window>

 2、使用形状绘制功能创建具有矢量内容的背景,不管是窗口尺寸改变,还是系统DPI改变,矢量内容都不会失真。

XAML

 1 <Window x:Class="WindowDemo.PathWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WindowDemo"
 7         mc:Ignorable="d"
 8         Title="PathWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
 9     <Grid>
10         <Canvas UseLayoutRounding="False" Width="180" Height="180">
11             <Canvas.Clip>
12                 <RectangleGeometry Rect="0.0,0.0,169.39037,161.76305"/>
13             </Canvas.Clip>
14             <Path Fill="#ff000000">
15                 <Path.Data>
16                     <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"/>
17                 </Path.Data>
18             </Path>
19         </Canvas>
20         <Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"></Button>
21     </Grid>
22 </Window>

 3、使用更简单的具有所有形状的WPF元素,如使用Border可以创建出具有圆角的窗口,使用Ellipse可以创建椭圆窗口。

XAML

 1 <Window x:Class="WindowDemo.IrregularElementWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WindowDemo"
 7         mc:Ignorable="d"
 8         Title="IrregularElementWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
 9     <Grid>
10         <Border Width="200" Height="400" BorderThickness="3" BorderBrush="Green" CornerRadius="20">
11             <Border.Effect>
12                 <DropShadowEffect></DropShadowEffect>
13             </Border.Effect>
14         </Border>
15 
16         <Button Content="关闭" HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click"></Button>
17     </Grid>
18 </Window>

如何移动不规则的窗口

不规则窗口不再具有标题栏,所以无法拖动窗口,幸运的是,系统封装了一个函数可以启动拖动模式。调用Window.DragMove()函数可以对窗口进行拖动

 XAML

1  <Grid Height="30" Background="LightBlue" VerticalAlignment="Top" Margin="0,35" Width="160" MouseDown="Grid_MouseDown">
2      <Label Content="点击我可以拖动窗口"></Label>
3  </Grid>

 XAML.cs

1         private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
2         {
3             if(e.LeftButton == MouseButtonState.Pressed)
4                 this.DragMove();
5         }

如何改变非矩形窗口的尺寸

对于非矩形的窗口,如果窗口的形状大体上还是矩形,或者窗口的内容基本是铺满整个窗口的,我们可以设置Window.ResizeMode为CanResizeWithGrip值为窗口添加一个用于改变窗口大小的手柄。如下所示:

但这种方式并不理想,最好的办法还是捕获鼠标,根据鼠标移动来动态计算窗口的大小。

原理如下:

1、放置一个热点区域,当鼠标进入时,变成可拖动状态。

2、鼠标按下时,捕获鼠标,根据鼠标拖动的大小调整窗口大小

3、鼠标松开时,释放鼠标。

具体实现方法如下:

1、放置一个Rectange/Border元素,设置背景为Transparent,宽度为5个单位,并显示在内容区域右边。

 1 <Window ... Height="450" Width="205" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
 2     <Grid>
 3         <Rectangle Width="5" Height="400" HorizontalAlignment="Right" Fill="Transparent" Cursor="SizeWE"></Rectangle>
 4         <Border Name="content" Margin="0,0,5,0" Height="400" BorderThickness="3" BorderBrush="Green" CornerRadius="20" Background="White">
 5             <Border.Effect>
 6                 <DropShadowEffect></DropShadowEffect>
 7             </Border.Effect>
 8         </Border>
 9     </Grid>
10 </Window>

说明:这里只添加了右侧调整大小的手柄,依次添加其它方向即可。

2、为Rectangle/Border添加鼠标按下/松开和移动的事件处理

1 <Rectangle 
2  ... MouseLeftButtonDown="Rectangle_MouseLeftButtonDown" MouseLeftButtonUp="Rectangle_MouseLeftButtonUp" MouseMove="Rectangle_MouseMove" />

3、事件处理逻辑如下:

 1 private bool isPressed = false;
 2 
 3 public IrregularElementWindowWithResize()
 4 {
 5     InitializeComponent();
 6 }
 7 
 8 private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 9 {
10     isPressed = true;
11 }
12 
13 private void Rectangle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
14 {
15     isPressed = false;
16     var rect = sender as Rectangle;
17     rect.ReleaseMouseCapture();  
18 }
19 
20 private void Rectangle_MouseMove(object sender, MouseEventArgs e)
21 {
22     if (isPressed)
23     {
24         Rectangle rect = sender as Rectangle;
25         rect.CaptureMouse();
26         var currentPos = e.GetPosition(this.content);
27         double newWidth = currentPos.X + 5;
28         if(newWidth > 0)
29         {
30             this.Width = newWidth + 5; 
31         }
32     }
33 }

 实现效果如下:

其它常用属性

窗口置顶(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中的常用控件(二)

参考资料

Window Class (System.Windows) | Microsoft Learn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201151.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【长文梳理Webserver核心】框架篇

感谢前人的总结&#xff0c;让一个小白快速成长&#xff0c;那我也贡献一份自己的力量~ 大框架梳理从main函数开始学习 大框架梳理 先摆图&#xff1a; 目光先放到最上面的两个小框架&#xff0c;半同步/半反应堆线程池和异步日志系统&#xff0c;日志系统晓得伐&#xff1f;…

jvm垃圾收集器简介

串行垃圾收集器 串行垃圾收集器&#xff0c;是指使用单线程进行垃圾回收&#xff0c;垃圾回收时&#xff0c;只有一个线程在工作&#xff0c;Java应用中的所有线程都要暂停&#xff0c;等待垃圾回收的完成。这种现象称之为STW(Stop-The-World)&#xff0c;一般的javaweb应用中…

深入理解 pnpm(Performant NPM) 的实现原理及其与 npm 的区别

深入理解 pnpm 的实现原理及其与 npm 的区别 在 JavaScript 生态系统中&#xff0c;包管理器是开发者日常工作中不可或缺的工具。npm&#xff08;Node Package Manager&#xff09;作为 Node.js 的默认包管理器&#xff0c;已经广泛应用于各种项目中。然而&#xff0c;随着项目…

略谈发展测量方法论-高敏雪老师的文章解读与收获

历史地看&#xff0c; GDP 被誉为“世纪性发明”&#xff0c;我们曾经将其视为衡量一国经济发展的重要工具&#xff1b;现实地看&#xff0c;“超越 GDP”是当前出现的带有国际性的口号&#xff0c;内在地包含着对 GDP作为发展指标的批评和替代。 如何看到发展&#xff1f; 如…

apisix云原生网关

定义 企业级网关通过域名、路由将请求分发到对应的应用上&#xff0c;通常承载数千个服务的流量&#xff0c;对稳定性有较高要求。 CNCF全景图 选型 Kubernetes抽象出两个核心概念&#xff1a;Service&#xff0c;为多个Pod提供统一的访问入口&#xff1b;Ingress&#xff…

【STM32-HAL库】实现微秒、毫秒、纳秒延时。(STM32F4系列)(附带工程下载链接)

使用了本代码后不能使用HAL库自带的HAL_Delay函数 使用了本代码后不能使用HAL库自带的HAL_Delay函数 使用了本代码后不能使用HAL库自带的HAL_Delay函数 一、新建工程 可以参考我的新建工程系列教程 stm32-HAL库cubeMX新建工程教程&#xff08;以F103C8T6为例&#xff09;ht…

【长文梳理webserver核心】核心类篇

前言 有三个核心组件支撑一个reactor实现 [持续] 的 [监听] 一组fd&#xff0c;并根据每个fd上发生的事件 [调用] 相应的处理函数。这三个组件就是 EventLoop 、Channel 以及 Poller 三个类&#xff0c;其中 EventLoop 可以看作是对业务线程的封装&#xff0c;而 Channel 可以看…

从零开始搭建一个node.js后端服务项目

一、下载node.js及配置环境 网上很多安装教程&#xff0c;此处就不再赘述了 版本信息 C:\Users\XXX>node -v v20.15.0C:\Users\XXX>npm -v 10.7.0 二、搭建node.js项目及安装express框架 在任意位置创建一个项目文件夹&#xff0c;此处项目文件夹名为test&#xff0…

右键菜单添加cmd

regedit 计算机\HKEY_CLASSES_ROOT\Directory\Background\shell\命令提示符\command 数据&#xff1a;cmd.exe /s /k title 命令提示符 或软件商店安装 Windows Terminal

基于element-ui的upload组件与阿里云oss对象存储的文件上传(采用服务端签名后直传的方式)

服务端签名后直传图解 步骤 1 开通阿里云OSS对象存储服务&#xff0c;创建新的Bucket 2 创建子账户获取密钥 创建用户 添加权限 后端 1 新建一个第三方服务的模块 third-party pom文件 <?xml version"1.0" encoding"UTF-8"?> <project x…

HAL+M4学习记录_3

一、HAL库开发框架 记录HAL学习过程 1.1 CMSIS CMSIS&#xff08;Cortex微控制器软件接口标准&#xff09;&#xff0c;用于提供用户和硬件间的接口&#xff0c;用户通过CMSIS标准对Cortex微控制器内部寄存器单元进行读写 1.2 HAL库 HAL&#xff08;硬件抽象层&#xff09;为…

加固与脱壳04 - 一些简单的脱壳方法

这里只讨论一些简单壳的脱壳方法及其原因。 FRIDA-DEXDump https://github.com/hluwa/FRIDA-DEXDump 适用于不需要研究那些被强保护起来的代码&#xff0c;只是想单纯的看看某个地方的业务逻辑。 原理&#xff1a; 对于完整的 dex&#xff0c;采用暴力搜索 dex035&#xf…

云栖实录 | Hologres3.0全新升级:一体化实时湖仓平台

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 姜伟华 | 阿里云智能集团资深技术专家、Hologres 负责人 丁 烨 | 阿里云智能集团产品专家、Hologres 产品负责人 活动&#xff1a; 2024 云栖大会 - 商用大数据计算与分析平台论…

基于Arduino的超声波和舵机模块集成使用

一.超声波模块和舵机模块集成使用 超声波模块&#xff1a;HC-SR04舵机模块&#xff1a;SG90目的&#xff1a;通过Arduino UNO核心板控制舵机旋转到不同位置&#xff0c;同时获取不同位置超声波模块和障碍物间的距离&#xff0c;配合控制算法&#xff0c;进行基于超声波智能避障…

需求10——通过改一个小bug来学习如何定位问题

在浏览我之前完成的一些小需求时&#xff0c;我发现了一个非常有价值的需求。这个需求可以让我深入了解系统中关于故障上报的功能。通过完善这个需求&#xff0c;我能够全面掌握整个故障上报的流程。 这个需求主要是关于故障上报流程中出现的问题。当前的流程如下&#xff1a;…

ML 系列:机器学习和深度学习的深层次总结(16) — 提高 KNN 效率-使用 KD 树和球树实现更快的算法

一、说明 在机器学习系列的第 16 节&#xff0c;我们重点介绍了提高 K 最近邻 &#xff08;KNN&#xff09; 算法的效率&#xff0c;这是一种广泛用于分类和回归任务的方法。虽然 KNN 简单有效&#xff0c;但对于大型数据集来说&#xff0c;其计算成本可能会令人望而却步。为了…

基于SpringBoot问卷调查系统小程序【附源码】

基于SpringBoot问卷调查系统小程序 效果如下&#xff1a; 管理员登录界面 管理员功能界面 调查人管理界面 问卷调查管理界面 问卷题目管理界面 用户登录界面 APP首页界面 公告信息界面 研究背景 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&…

组织病理学图像中的再识别|文献速递--基于多模态-半监督深度学习的病理学诊断与病灶分割

Title 题目 Re-identification from histopathology images 组织病理学图像中的再识别 01 文献速递介绍 在光学显微镜下评估苏木精-伊红&#xff08;H&E&#xff09;染色切片是肿瘤病理诊断中的标准程序。随着全片扫描仪的出现&#xff0c;玻片切片可以被数字化为所谓…

怎么在单片机裸机程序中移植EasyLogger?

1、介绍 EasyLogger 是一款超轻量级、高性能的C日志库&#xff0c;非常适合对资源敏感的软件项目。例如&#xff1a;IoT产品、可穿戴设备、智能家居等等。相比log4c、zlog这些知名的C日志库&#xff0c;EasyLogger的功能更加简单&#xff0c;提供给用户的接口更少&#xff0c;但…

肺腺癌预后新指标:全切片图像中三级淋巴结构密度的自动化量化|文献精析·24-10-09

小罗碎碎念 本期这篇文章&#xff0c;我去年分享过一次。当时发表在知乎上&#xff0c;没有标记参考文献&#xff0c;配图的清晰度也不够&#xff0c;并且分析的还不透彻&#xff0c;所以趁着国庆假期重新分析一下。 这篇文章的标题为《Computerized tertiary lymphoid structu…