WPF中的Window类

控件分类

在第一篇文章.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.xdnf.cn/news/1559256.html

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

相关文章

高性能缓存方案 —— Caffeine

一、简介 Caffeine是一个高性能的Java缓存库&#xff0c;它提供了本地缓存的功能。 Caffeine和Redis都是内存级别的缓存&#xff0c;为什么要使用在这两缓存作为二级缓存&#xff0c;它们两有什么区别呢? 虽然它们都是内存级别的缓存&#xff0c;但是Redis是需要单独部署的&…

【开源风云】从若依系列脚手架汲取编程之道(五)

&#x1f4d5;开源风云系列 &#x1f34a;本系列将从开源名将若依出发&#xff0c;探究优质开源项目脚手架汲取编程之道。 &#x1f349;从不分离版本开写到前后端分离版&#xff0c;再到微服务版本&#xff0c;乃至其中好玩的一系列增强Plus操作。 &#x1f348;希望你具备如下…

鸿蒙OS投票机制

(基于openharmony5.0) 投票机制 param get | grep ohos.boot.time 图 投票机制参数图 只有当所有的投票完成&#xff0c;开机动画才会退出&#xff0c;整理需要投票的系统应用&#xff08;三方应用不参与投票&#xff09;如下图所示&#xff1a; 以进程foundation为例&…

Python案例--copy复制

在Python编程中&#xff0c;数据的复制是一个常见且重要的操作&#xff0c;它涉及到赋值、浅拷贝和深拷贝三种不同的概念。正确理解这三种操作对于编写高效且正确的程序至关重要。本文将通过一个简单的Python示例&#xff0c;探讨这三种数据复制方式的区别及其应用场景&#xf…

计算机视觉之OpenCV vs YOLO

好多开发者希望搞明白OpenCV 和YOLO区别&#xff0c;实际上&#xff0c;二者在计算机视觉领域都有广泛应用&#xff0c;但它们有很大的不同。 一、OpenCV 概述 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它…

软考攻略/超详细/系统集成项目管理工程师/基础知识分享12

5.1 软件工程定义&#xff08;了解&#xff09; 软件工程是指应用计算机科学、数学及管理科学等原理&#xff0c;其目的是提高软件生产率、提高软件质量、降低软件成本。 5.2 软件需求&#xff08;掌握&#xff09; 5.2.1 需求的层次&#xff08;掌握&#xff09; 软件需求是指…

打造直播美颜平台的关键技术:视频美颜SDK的深度解析

本篇文章&#xff0c;小编将深入解析视频美颜SDK的关键技术&#xff0c;探讨其在打造直播美颜平台中的作用。 一、视频美颜SDK的定义与功能 视频美颜SDK是一套专门为实时视频处理而设计的软件开发工具包。其主要功能包括人脸检测、肤色美化、瑕疵修复、虚化背景、实时滤镜等。…

chaos官方给的V-Ray材质优化器怎么样?

V-Ray材质优化器是一个为3ds Max设计的MAX脚本&#xff0c;它通过以下方式优化场景&#xff0c;提高渲染速度&#xff01; V-Ray材质优化器安装包可找【成都渲染101云渲染&#xff0c;云渲码6666】提供&#xff01; ​ 通过创建一个新的UV通道并使用平面映射算法展开场景对象。…

vue3 vue2

vue3.0是如何变快的&#xff1f; diff算法优化 vue2的虚拟dom是进行全局的对比。vue3 新增了静态标记&#xff08;patchFlag&#xff09; 在与上次虚拟节点进行比较的时候&#xff0c;只对比带有patch Flag的节点&#xff0c;并且可以通过flag的信息得知当前节点要对比的具体内…

CRM客户关系管理系统全面解析

CRM&#xff08;Customer Relationship Management&#xff09;客户关系管理系统是一种以客户为中心的商业策略和技术框架&#xff0c;旨在通过对客户资料的收集、管理和分析&#xff0c;提升企业的市场竞争力&#xff0c;从而实现业务增长和客户满意度的提高。以下是对CRM系统…

移动美容师是什么?职业前景如何?连锁美业门店管理系统拓客系统Java源码

移动美容师是一种为客户提供上门美容服务的专业人士。与传统美容院或美容店不同&#xff0c;移动美容师可以根据客户的需求和预约&#xff0c;在客户指定的时间和地点进行美容护理、美甲、美发等项目。 这种服务形式为顾客提供了更加便捷、个性化的美容体验&#xff0c;同时也…

华为OD机试 - 采样过滤(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

YOLO11涨点优化:注意力魔改 | 双重注意力机制DoubleAttention,有效地捕获图像中不同位置和不同特征的重要性

💡💡💡本文改进内容: DoubleAttention该网络结构采用双重注意力机制,包括Spatial Attention和Channel Attention,有效地捕获图像中不同位置和不同特征的重要性 💡💡💡本文改进:分别加入到YOLO11的backbone、neck、detect,助力涨点 改进1结构图: 改进2结构图…

STM32—W25Q64

1.W25Q64简介 W25Oxx系列是一种低成本、小型化、使用简单的非易失性存储器 易失性存储器 般就是SRAM、DRAM等非易失性存储器 般就是E2PROM、Flash等常应用于数据存储、字库存储、固件程序存储等场景存储介质&#xff1a;Nor Flash(闪存)时钟频率&#xff1a;80MHz / 160MHz(…

C语言 | 第十三章 | 二维数组 冒泡排序 字符串指针 断点调试

P 120 数组应用案例 2023/1/29 一、应用案例 案例一&#xff1a;创建一个char类型的26个元素的数组&#xff0c;分别 放置’A’-Z‘。使用for循环访问所有元素并打印出来。提示&#xff1a;字符数据运算 ‘A’1 -> ‘B’ #include<stdio.h>void main(){/*创建一个c…

Mysql中创建用户并设置任何主机连接

Mysql中创建用户并设置任何主机连接 文章目录 Mysql中创建用户并设置任何主机连接背景解决方式 背景 在linux上安装mysql,默认用户是root,但是用navicat连接不了,必须要用ssh隧道连接,现在想用任何主机只要输入账号密码之后就可以连接 解决方式 #创建一个指定用户和IP链接的用…

通过祖先序列重建辅助工程化UDP-糖基转移酶-文献精读64

Engineering the Substrate Specificity of UDP-Glycosyltransferases for Synthesizing Triterpenoid Glycosides with a Linear Trisaccharide as Aided by Ancestral Sequence Reconstruction 通过祖先序列重建辅助工程化UDP-糖基转移酶的底物特异性&#xff0c;用于合成具…

股市有人吹的“哨音”也应倾听

国庆节前&#xff0c;深圳东方港湾投资管理股份有限公司董事长但斌发微博警告说&#xff1a;“这样暴涨&#xff0c;必有暴跌&#xff0c;这次如果再被套住&#xff0c;该动员的力量都动员了解套将遥遥无期”他这样警告&#xff0c;就与新冠病毒刚在武汉爆发时的“吹哨人”起的…

重头开始嵌入式第四十六天(硬件 ARM裸机开发 ADC 中断 UART)

目录 ADC使用 1.什么是ADC&#xff1f; 一、功能 二、工作原理 三、参数指标 四、应用领域 2.如何配置s3c2440中的adc&#xff1f; 中断 1.什么是中断&#xff1f; 一、定义 二、中断的作用 三、中断的类型 四、中断处理过程 2.如何配置中断&#xff1f; UART 1…

一站式服务,产业园运营让创业更轻松!

一站式服务&#xff0c;也被称为“一条龙服务”或“全流程服务”&#xff0c;它是指企业或机构为了满足客户或用户的需求&#xff0c;整合内部资源&#xff0c;通过优化服务流程、提高服务效率&#xff0c;从而提供从咨询、受理、办理到反馈等各个环节的完整、连续、高效的服务…