C# winform下悬挂窗口的简易实现
前两天在工作中用C#实现了一个WinForm下的悬挂窗口;
之前在网上搜索了几下,没有发现类似的说明,特在此记录一下。
特别说明:所谓悬挂窗口,就是类似QQ聊天工具的一个功能,当窗口放到桌面的上边界时自动收缩成一个小条隐藏起来;而一旦鼠标再次接触到上述边界的时候,窗口又会自动展开。
实现方法有两类,一是窗口内实现悬挂,在窗口内创建一个小的Panel,正常时不可见,在悬挂是显示,
悬挂时设置窗口标题栏不显示和窗口高度为该Panel高度;二是单独窗口悬挂,创建新的窗口作为悬挂时的显示条,同时隐藏掉主窗口。
一、窗口内实现悬挂
在LocationChanged事件内判断是否到桌面上边界,通过定时器判断当前鼠标位置
(System.Windows.Forms.Control.MousePosition)是否离开窗口区域,或者进入窗口区域。
实现代码。
二、单独窗口悬挂
本来不想考虑第二种方式的,但是后来发现需要悬挂的窗口设置高度居然无效,是一个从DevComponents.DotNetBar.Office2007RibbonForm继承的窗口类。
实现思路基本一样,只是需要注意的是判断当前鼠标的位置需要分不同的窗口转换坐标,还有其他细节见代码。
定义变量:
bool m_bXuanGua = false; //窗体是否处在悬挂状态
HideFlagForm m_HideFlagForm = new HideFlagForm(); //悬挂标志窗口
主要方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | /// <summary> /// 窗口位置被拖动的响应事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormMain_LocationChanged( object sender, EventArgs e) { if (Location.Y < 0) { Top = 0; m_bXuanGua = true ; } else { m_bXuanGua = false ; plHideForm.Visible = false ; } SetHideFlagFormPos(); } /// <summary> /// 设置标志窗体的位置和大小 /// </summary> private void SetHideFlagFormPos() { m_HideFlagForm.Left = this .Left; m_HideFlagForm.Top = this .Top; m_HideFlagForm.Width = this .Width; m_HideFlagForm.Height = 10; } /// <summary> /// 悬挂或者展开窗体 /// </summary> private void ShowHideForm() { Point pt = new Point(System.Windows.Forms.Control.MousePosition.X, System.Windows.Forms.Control.MousePosition.Y); Point pt2 = new Point(); if ( this .Visible) pt2 = PointToClient(pt); else pt2 = m_HideFlagForm.PointToClient(pt); int iHight = 0; if ( this .Visible) iHight = Height; else iHight = m_HideFlagForm.Height; if (pt2.X < 0 || pt2.X > Width || pt2.Y > iHight) //在窗体客户区域之外时 { if (m_bXuanGua && FormBorderStyle != FormBorderStyle.None) { FormBorderStyle = FormBorderStyle.None; SetHideFlagFormPos(); this .Hide(); m_HideFlagForm.Show(); SetHideFlagFormPos(); } } else //在窗体客户区域之内 { if (m_bXuanGua && FormBorderStyle != FormBorderStyle.Sizable) { FormBorderStyle = FormBorderStyle.Sizable; m_HideFlagForm.Hide(); this .Show(); } } } /// <summary> /// 定时器 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void tmCursorPosCalc_Tick( object sender, EventArgs e) { if (System.Windows.Forms.Control.MouseButtons == MouseButtons.Left) return ; //在鼠标左键为按下时,认为窗口处在拖动状态,暂停鼠标位置的判断 ShowHideForm(); } /// <summary> /// 窗口大小改变事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FormMain_Resize( object sender, EventArgs e) { m_HideFlagForm.Left = Left; m_HideFlagForm.Width = Width; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述