Winform中实现拖动 Windows 边缘来调整其大小

news/2024/9/30 0:07:09

Winform中实现无边框窗体只需要设置一个属性FormBorderStyle = FormBorderStyle.None;即可,或者在设计器中直接设置。无边框表单的结果是丢失了标题栏和控制框(最小化、最大值和关闭按钮)。如果没有标题栏,则无法拖动和移动窗口。如果没有边框,则无法拖动 Windows 边缘来调整其大小。移动表单非常简单,但边缘拖动调整大小有点棘手。

下面通过监听鼠标事件和调整光标形状,实现了一个用户可以通过拖拽窗体边缘来调整窗体大小的功能。同时,它还确保了当鼠标离开窗体时,光标形状会恢复为默认的箭头形状。

先上效果图

具体来说,它允许用户通过拖动鼠标来改变窗体的大小。以下是代码的工作原理概述:

1.初始化:

在构造函数 Form1() 中,为 Form1 实例注册了两个事件处理器:MouseMove 用于处理鼠标移动时的行为,MouseLeave 用于处理鼠标离开窗体时的行为。

2.鼠标移动处理 (Main_MouseMove):

如果鼠标接近右下角,则显示双向对角线箭头。

如果鼠标接近右侧,则显示水平箭头。

如果鼠标接近底部,则显示垂直箭头。

Cursors.SizeNWSE: 允许同时改变窗体的宽度和高度。

Cursors.SizeWE: 只允许改变窗体的宽度。

Cursors.SizeNS: 只允许改变窗体的高度。

当鼠标在窗体内移动时,会触发 MouseMove 事件。

如果鼠标左键被按下,并且光标形状是某种尺寸调整箭头(Cursors.SizeNWSE, Cursors.SizeWE, 或 Cursors.SizeNS),则根据当前光标类型调整窗体的宽度和/或高度。

根据鼠标位置与窗体边缘的距离(5像素内),动态地改变光标形状以提示用户可以进行何种类型的尺寸调整:

如果鼠标不在这些区域,则恢复默认的箭头光标。

3.鼠标离开窗体处理 (Main_Leave):

当鼠标指针离开窗体范围时,将光标恢复到默认的箭头状态。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WindowsFormsApp7
{public partial class Form1 : Form{private int borderSize = 2;[DllImport("user32.DLL", EntryPoint = "ReleaseCapture")]private extern static void ReleaseCapture();[DllImport("user32.DLL", EntryPoint = "SendMessage")]private static extern void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam);private void panelTitleBar_MouseDown(object sender, MouseEventArgs e)  //panel的MouseDown事件
        {ReleaseCapture();SendMessage(this.Handle, 0x112, 0xf012, 0);}public Form1(){InitializeComponent();this.Padding = new Padding(borderSize);this.BackColor = Color.FromArgb(245, 245, 255); //98, 102, 244);// this.ControlBox = false;this.Text = string.Empty;this.FormBorderStyle = FormBorderStyle.None;//this.WindowState = FormWindowState.Maximized;this.MaximizedBounds = Screen.FromHandle(this.Handle).WorkingArea;           MouseMove += Main_MouseMove;MouseLeave += Main_Leave; // 有控件在边缘时,处理一下更好一些
        }private void Form1_Load(object sender, EventArgs e){this.panelMenu.Width = 180;}#region 退出按钮private void appExit(object sender, EventArgs e){//退出按钮
            Application.Exit();}#endregion#region 最大化按钮private void butMax_Click(object sender, EventArgs e){   //最大化按钮if (this.WindowState == FormWindowState.Normal){ this.WindowState = FormWindowState.Maximized;}else{this.WindowState = FormWindowState.Normal;}}#endregion#region 最小化按钮private void butMin_Click(object sender, EventArgs e){//最小化按钮this.WindowState = FormWindowState.Minimized;}#endregion#region 侧面菜单栏折叠与展开//private void CollapseMenu()//{//    if (this.panel1.Width > 50)//    {//        this.panel1.Width = 50;//        this.pictureBox1.Visible = false;//        //this.button7.Dock = DockStyle.Fill;//        foreach (Button control in panel1.Controls.OfType<Button>())//        {//            control.Text = "";//            control.ImageAlign = ContentAlignment.MiddleCenter;//            control.Padding = new Padding(0);//        }//    }//    else//    {//        this.panel1.Width = 180;//        this.pictureBox1.Visible = true;//        //this.button7.Dock = DockStyle.Right;//        foreach (Button control in panel1.Controls.OfType<Button>())//        {//            control.Text = control.Tag.ToString();//            control.ImageAlign = ContentAlignment.MiddleLeft;//            control.Padding = new Padding(45, 0, 0, 0);//        }//    }//}private void CollapseMenu(){//这段C#代码实现了一个CollapseMenu()方法,用于控制侧边栏菜单的折叠和展开//首先判断当前侧边栏的宽度是否大于200,如果是,则将宽度设置为100,隐藏图标,//将菜单按钮的Dock属性设置为Top,//设置面板的内边距为上边10像素,下左右为0,//并遍历所有的菜单按钮,将它们的文本设置为空,//图像对齐方式设置为居中,内边距设置为0。//如果当前侧边栏的宽度小于等于200,//就将宽度设置为260,显示图标,将菜单按钮的Dock属性设置为None,//设置面板的内边距为上下左右都为0,//并遍历所有的菜单按钮,将它们的文本设置为按钮的Tag属性值前面加两个空格,//图像对齐方式设置为左对齐,文本对齐方式设置为右对齐,//按钮文本和图像的相对位置设置为文本在图像左侧,//内边距设置为上0像素,左边距为10像素,下右边距为0。if (this.panelMenu.Width > 100){panelMenu.Width = 50;iconPictureBox1.Visible = false;//btnMenu.Dock = DockStyle.Top;//this.panelMenu.Padding = new Padding(0, 10, 0, 0);foreach (var mybutton in this.panelMenu.Controls.OfType<Button>()) //筛选出panelMenu内所有属于Button类型的子控件
                {mybutton.Text = "";mybutton.ImageAlign = ContentAlignment.MiddleCenter; //将其图像对齐方式设置为居中对齐mybutton.Padding = new Padding(0); //内边距设为0
                }}else{panelMenu.Width = 180;iconPictureBox1.Visible = true;//btnMenu.Dock = DockStyle.None;//this.panelMenu.Padding = new Padding(0, 0, 0, 0);foreach (var mybutton in this.panelMenu.Controls.OfType<Button>()) //筛选出panelMenu内所有属于Button类型的子控件
                {mybutton.Text =mybutton.Tag.ToString();     //将控件的Tag赋值给Text     "  " + mybutton.ImageAlign = ContentAlignment.MiddleLeft;mybutton.TextAlign = ContentAlignment.MiddleRight;mybutton.TextImageRelation = TextImageRelation.ImageBeforeText;  //Text和Image位置关系mybutton.Padding = new Padding(30, 0, 0, 0);}}}//侧面菜单栏折叠与展开private void btnMenu_Click(object sender, EventArgs e){CollapseMenu();}#endregion#region 保持整体布局不变private void AdjustForm(){switch (this.WindowState){case FormWindowState.Normal:if (this.Padding.Top != borderSize)this.Padding = new Padding(borderSize);break;case FormWindowState.Minimized:this.Padding = new Padding(8, 8, 8, 8);break;case FormWindowState.Maximized:break;default:break;}}private void Form1_Resize(object sender, EventArgs e){AdjustForm();}#endregion#region 控制无边框拉伸private void Main_MouseMove(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left)//左键按下移动,拖拽调整大小
            {// MousePosition的参考点是屏幕的左上角,表示鼠标当前相对于屏幕左上角的坐标。this.Left和this.Top的参考点也是屏幕if (Cursor == Cursors.SizeNWSE) // 倾斜拖拽
                {// 改变窗体宽和高的代码,其宽高为鼠标屏幕位置减去窗体的Left,Top距离this.Width = MousePosition.X - this.Left;this.Height = MousePosition.Y - this.Top;}else if (Cursor == Cursors.SizeWE) // 水平拖拽
                {Width = MousePosition.X - this.Left;}else if (Cursor == Cursors.SizeNS) // 垂直拖拽
                {Height = MousePosition.Y - this.Top;}}//鼠标移动过程中,坐标时刻在改变//当鼠标移动时横坐标距离窗体右边缘5像素以内且纵坐标距离下边缘也在5像素以内时,要将光标变为倾斜的箭头形状if (e.Location.X >= this.Width - 5 && e.Location.Y > this.Height - 5){this.Cursor = Cursors.SizeNWSE; // 右下角 双向对角线光标
            }//当鼠标移动时横坐标距离窗体右边缘5像素以内时,要将光标变为双向水平箭头形状else if (e.Location.X >= this.Width - 5){this.Cursor = Cursors.SizeWE; // 双向水平光标
            }//当鼠标移动时纵坐标距离窗体下边缘5像素以内时,要将光标变为垂直水平箭头形状else if (e.Location.Y >= this.Height - 5){this.Cursor = Cursors.SizeNS; // 双向垂直光标
            }//否则,以外的窗体区域,鼠标星座均为单向箭头(默认)else this.Cursor = Cursors.Arrow;}private void Main_Leave(object sender, EventArgs e){Cursor = Cursors.Arrow;// 移出窗体变为正常
        }#endregion}
}

 

通过这种方式,当用户将鼠标悬停在窗体边缘并拖动时,窗体会相应地改变其大小,提供了直观的用户体验。这段代码没有涉及到实际的拖动整个窗体的位置,仅关注于改变窗体的尺寸。如果需要实现窗体位置的拖动,还需要额外的逻辑来处理标题栏或其他指定区域的拖动行为。

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

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

相关文章

《Programming from the Ground Up》阅读笔记:p117-p146

《Programming from the Ground Up》学习第8天,p117-p146总结,总计30页。 一、技术总结 1.共享函数用法示例 (1)不使用共享函数 linux.s: # filename:linux.s# system call numbers(按数字大小排列,方便查看) .equ SYS_READ, 0 .equ SYS_WRITE, 1 .equ SYS_OPEN, 2 .equ SY…

《Python 基础篇》六:面向对象

Python 中的面向对象。Author: ACatSmiling Since: 2024-09-27什么是对象 对象:是内存中专门用来存储数据的一块区域。 对象中可以存放各种数据,比如:数字、布尔值、代码。 对象由三部分组成:对象的标识(id) 对象的类型(type) 对象的值(value)面向对象(oop) Python…

9.23课堂作业

我所选择的主题是安全教育。在校园内外,我们经常听到的、看到的一些不安全事故频繁发生。尽管在校园内,也会有无端横祸向我们飞来,血的教训让我们懂得,校园安全与师生密切相关,关系到学生能否健康成长,完成学业。关系到老师能否在个宁静安全的环境中教书育人。校园安全是…

streamlit

示例代码import streamlit as st import pandas as pd from pathlib import Path@st.cache_data def load_data_from_csv(file_path):return pd.read_csv(file_path)if __name__ == __main__:file_path = Path(__file__).parent.parent / resources / data.csvdata = load_data…

PlantSimulation的socket交互之TCP

PlantSimulation的socket交互之TCP1.python的socket TCP客户端建立 其实可以任选python或plantsimulation作为客户端,博主因研究需要,将python设为客户端。plant设为服务器。1 """2 Created on Sat December 14 21:00:00 20213 @author: Zhang Litong- Nanjin…

2024-2025-1 20241419《计算机基础与程序设计》第一周学习总结

课程 要求 目标:基于VirtualBox虚拟机安装Ubuntu 作业正文:基于VirtualBox虚拟机安装Ubuntu 教材学习内容总结 1.计算系统:由软件、硬件及其管理的数据组成的用于解决问题以及与其所处环境进行交互的一种动态实体。 2.计算系统的分层:计算系统的各个具体组成部分。 3.抽象:…

Rhino基础操作3 - 出图篇

Rhino建模后出一系列的图的操作:建模后做倒角、利用快照切换视图。 出图有:纯线稿、截面图、剖面图、模型的说明书类、模型渲染图。注:非结构建模专业,纯粹是用Rhino写实用新型专利,所以学了下Rhino的建模。不理解最简面、曲线阶数的影响等,请原谅。--本篇导航--圆角(假…

vscode中文乱码问题

vscode中文乱码解决方法 简单粗暴:文件——>首选项——>设置——>搜索设置——>encoding——>Files:Encoding ——> gbk 修改实现注:可在同文件夹下实现效果; 如果不是固定常用,方法二: 这个就在规定文本文件实现;