WPF制作无边框窗体、圆角窗体、支持改变大小、拖动分屏等(一)

您所在的位置:网站首页 Unity拖拽边缘改变大小 WPF制作无边框窗体、圆角窗体、支持改变大小、拖动分屏等(一)

WPF制作无边框窗体、圆角窗体、支持改变大小、拖动分屏等(一)

2024-06-22 03:21| 来源: 网络整理| 查看: 265

目录 概述需求说明制作无边框窗体窗体拖动、拖动分屏解决拖动问题窗体功能按钮 使用RRQMSkin创建无边框窗体结束

概述

Windows Presentation Foundation (WPF) 是一个可创建桌面客户端应用程序的 UI 框架。 WPF 开发平台支持广泛的应用开发功能,包括应用模型、资源、控件、图形、布局、数据绑定、文档和安全性。 此框架是 .NET Framework 的一部分,因此,在未来如果想快速的开发桌面软件,WPF腚是你的不二选择。

需求说明

WPF既然是桌面软件UI,那一定绕不开桌面软件的多元化(chan pin jing li de chou pi)显示方式,最常见的就是无边框窗体、圆角窗体、窗体阴影等,同时还需要支持改变窗口大小、响应拖动分屏等。本文也会从这几个需求入手,打造一个让各位猿友满意的窗体。

开整(分割线搞个仪式)

制作无边框窗体

思路: 无边框窗体比较好办,思路就是设置窗体属性WindowStyle为None,这时无边框窗体就创建好了,而且支持改变尺寸,但是为了普适性,需要对窗体进行装饰,比如:窗体拖动、拖动分屏、窗体功能按钮、窗体是否支持改变大小等,这些都需要代码参与。

窗体拖动、拖动分屏

拖动操作一般是在窗体头操作的,所以需要对窗体进行Grid分行。然后在title的Grid里注册鼠标移动事件,然后在后台控制窗体拖动(title的Grid背景色必须赋值,哪怕是透明色,不然不会命中测试)。实际上在调用DragMove方法时,窗体就已经支持了左右分屏以及全屏,但是问题就是:全屏是满屏,把任务栏也遮住了,其次满屏后不能再拖动为正常尺寸。

namespace WpfApp1 { /// /// Window1.xaml 的交互逻辑 /// public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void title_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton== MouseButtonState.Pressed) { this.DragMove(); } } } } 解决拖动问题

(1)首先就是最大化遮挡任务栏问题,可以通过重写OnStateChanged事件,在最大化时设置窗体边框以及最大允许尺寸(最大尺寸由工作区域+16组成,16的数字来源于经验),但是由于该事件需要激活,所以需要在Loaded空调用一次。

namespace WpfApp1 { /// /// Window1.xaml 的交互逻辑 /// public partial class Window1 : Window { public Window1() { InitializeComponent(); this.Loaded += this.Window1_Loaded; } private void Window1_Loaded(object sender, RoutedEventArgs e) { OnStateChanged(null); } private void title_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton== MouseButtonState.Pressed) { this.DragMove(); } } protected override void OnStateChanged(EventArgs e) { switch (this.WindowState) { case WindowState.Maximized: this.MaxWidth = SystemParameters.WorkArea.Width + 16; this.MaxHeight = SystemParameters.WorkArea.Height + 16; this.BorderThickness = new Thickness(5); //最大化后需要调整 break; case WindowState.Normal: this.BorderThickness = new Thickness(0); this.MaxWidth = SystemParameters.WorkArea.Width + 16; this.MaxHeight = SystemParameters.WorkArea.Height + 16; break; } } } }

(2)其次解决最大化时拖动问题,我们可以考虑在最大化时拖动时,先设置WindowState为Normal,但是直接这样做会导致鼠标和拖动点之间存在很大间距,所以还需要设置窗体位置。

namespace WpfApp1 { /// /// Window1.xaml 的交互逻辑 /// public partial class Window1 : Window { public Window1() { InitializeComponent(); this.Loaded += this.Window1_Loaded; } private void Window1_Loaded(object sender, RoutedEventArgs e) { OnStateChanged(null); } private void title_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { if (this.WindowState == WindowState.Maximized) { WindowState = WindowState.Normal; Point point = e.MouseDevice.GetPosition(this); Left = point.X - this.title.ActualWidth * point.X / SystemParameters.WorkArea.Width; Top = point.Y - this.title.ActualHeight * point.Y / SystemParameters.WorkArea.Height; } this.DragMove(); } } protected override void OnStateChanged(EventArgs e) { switch (this.WindowState) { case WindowState.Maximized: this.MaxWidth = SystemParameters.WorkArea.Width + 16; this.MaxHeight = SystemParameters.WorkArea.Height + 16; this.BorderThickness = new Thickness(5); //最大化后需要调整 break; case WindowState.Normal: this.BorderThickness = new Thickness(0); this.MaxWidth = SystemParameters.WorkArea.Width + 16; this.MaxHeight = SystemParameters.WorkArea.Height + 16; break; } } } } 窗体功能按钮

窗体的功能按钮是控制窗体的最重要控件。一般的有最小化、正常化切换、最大化三种功能按钮。但是不能直接在title里面直接部署这三个按钮,因为这样的话按钮也会响应拖动命令,这是我们所不希望的。所以必须重新对窗体头布局。然后对按钮注册click事件。 在这里插入图片描述

namespace WpfApp1 { /// /// Window1.xaml 的交互逻辑 /// public partial class Window1 : Window { public Window1() { InitializeComponent(); this.Loaded += this.Window1_Loaded; } private void Window1_Loaded(object sender, RoutedEventArgs e) { OnStateChanged(null); } private void title_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { if (this.WindowState == WindowState.Maximized) { WindowState = WindowState.Normal; Point point = e.MouseDevice.GetPosition(this); Left = point.X - this.title.ActualWidth * point.X / SystemParameters.WorkArea.Width; Top = point.Y - this.title.ActualHeight * point.Y / SystemParameters.WorkArea.Height; } this.DragMove(); } } protected override void OnStateChanged(EventArgs e) { switch (this.WindowState) { case WindowState.Maximized: this.MaxWidth = SystemParameters.WorkArea.Width + 16; this.MaxHeight = SystemParameters.WorkArea.Height + 16; this.BorderThickness = new Thickness(5); //最大化后需要调整 break; case WindowState.Normal: this.BorderThickness = new Thickness(0); this.MaxWidth = SystemParameters.WorkArea.Width + 16; this.MaxHeight = SystemParameters.WorkArea.Height + 16; break; } } private void Button_Click(object sender, RoutedEventArgs e) { this.WindowState = WindowState.Minimized; } private void Button_Click_1(object sender, RoutedEventArgs e) { if (this.WindowState == WindowState.Normal) { this.WindowState = WindowState.Maximized; } else { this.WindowState = WindowState.Normal; } } private void Button_Click_2(object sender, RoutedEventArgs e) { this.Close(); } } } 使用RRQMSkin创建无边框窗体

实际上以上代码只能实现比较简单的功能,并不完全具备普适性,所以无边框窗体已经被本猿封装到了RRQMSkin中,如果大家想直接使用的话直接在Nuget搜索RRQMSkin即可,具体操作如下: 在这里插入图片描述 在这里插入图片描述 添加好引用后,在主窗体替换继承类为RRQMWindow即可(包括后台代码)。

namespace WpfApp1 { /// /// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : RRQMSkin.Windows.RRQMWindow { public MainWindow() { InitializeComponent(); } } } 结束

OK,一个无边框窗体就创建完成了,下节说创建圆角窗体。

最后希望这篇博客能帮到各位猿友,当然如果还有什么不明白的,可以私信本猿哦,QQ群:234762506



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3