最近在编写C/S结构应用程序时,感觉窗体的标题栏样式太死板了,标题文字不能更改大小、颜色、字体等,按钮不能隐藏等问题,在网上也查找了许多相关的资料,没有找到合适的解决方案,发现许多人也在寻求这个问题,最后我决定自己研究动手画一个标题栏出来,经过今天一天的研究与编写,终于完成全部功能,现公布一下我的设计思路。
一、去掉Form类自带的标题栏
要去掉自带的标题栏有两种方法,第一方法是直接将FormBorderStyle设为 System.Windows.Forms.FormBorderStyle.None,但设置过后,窗体无法改变大小,考虑到后期这些功能还是需要的,所以我采用了第二种方法,第二种方法是可以忽略FormBorderStyle,只需要将ControlBox设为 false,并将Text设为空即可,这种方法隐藏标题栏,若FormBorderStyle不是固定模式,则可以通过拉伸窗体边框改变大小的。
二、创建自定义窗体类
首先创建一个窗体,如下图:
然后去掉Text默认的文字,并将ControlBox设为 false,此时标题栏将自动隐藏掉了,如下图:
去掉标题栏后,就需要重画新的标题栏,画标题栏很简单,方法也很多,我这里是采用一个Panel,将Dock设为Top,让其项部固定,并设高度为30像素,再在其中添加三个按钮,依次为:button1(关闭),button2(最大化),button3(最小化),三个按钮的设为Size相同,且将Anchor都设为Top Right Bottom,这样就实现了让三个按钮在右边固定位置,如下图:
界面部份已经完工,剩下的就是编写代码了,由于代码较多,我先将代码贴出来,稍后再讲解。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ZControls { /// <summary> /// Copyright Zuowenjun /// Site Url:http://www.zuowenjun.cn /// QQ:77321032 /// Description:自定义窗体样式,实现标题可自定义化 /// </summary> public partial class ZForm : Form { private bool moving = false; private Point oldMousePosition; public new FormBorderStyle FormBorderStyle { get { return base.FormBorderStyle; } set { if (value != FormBorderStyle.Sizable && value != FormBorderStyle.SizableToolWindow) { titlepanel.Controls.Remove(button2); } base.FormBorderStyle = value; } } #region 隐藏父类的属性,使其不可见 [Browsable(false)] public new string Text { get { return titlelabel.Text; } set { } } [Browsable(false)] public new bool ControlBox { get { return false; } set { base.ControlBox = false; } } #endregion [Browsable(true)] [EditorBrowsable(EditorBrowsableState.Always)] [Description("窗体标题")] public string Title { get { return titlelabel.Text; } set { titlelabel.Text = value; } } [Browsable(true)] [EditorBrowsable(EditorBrowsableState.Always)] [Description("窗体标题字体样式")] public Font TitleFont { get { return titlelabel.Font; } set { titlelabel.Font = value; } } [Browsable(true)] [EditorBrowsable(EditorBrowsableState.Always)] [Description("窗体标题字体颜色")] public Color TitleColor { get { return titlelabel.ForeColor; } set { titlelabel.ForeColor = value; } } [Browsable(true)] [EditorBrowsable(EditorBrowsableState.Always)] [Description("窗体标题栏背景色")] public Color TitleBarBackColor { get { return titlepanel.BackColor; } set { titlepanel.BackColor = value; } } public new bool MaximizeBox { get { return titlepanel.Contains(button2); } set { if (!value) { titlepanel.Controls.Remove(button2); } else if (!titlepanel.Contains(button2)) { titlepanel.Controls.Add(button2); } } } public new bool MinimizeBox { get { return titlepanel.Contains(button3); } set { if (!value) { titlepanel.Controls.Remove(button3); } else if (!titlepanel.Contains(button3)) { titlepanel.Controls.Add(button3); } } } private void ResetTitlePanel() { base.ControlBox = false; base.Text = null; SetToolTip(button1, "关闭"); button2.Size = button1.Size; SetToolTip(button2, "最大化或还原"); button3.Size = button1.Size; SetToolTip(button3, "最小化"); } private void SetToolTip(Control ctrl, string tip) { new ToolTip().SetToolTip(ctrl, tip); } public ZForm() { InitializeComponent(); ResetTitlePanel(); } private void Titlebutton_Click(object sender, EventArgs e) { Button btn = (Button)sender; switch (btn.Tag.ToString()) { case "close": { this.Close(); break; } case "max": { if (this.WindowState == FormWindowState.Maximized) { this.WindowState = FormWindowState.Normal; } else { this.WindowState = FormWindowState.Maximized; } break; } case "min": { if (this.WindowState != FormWindowState.Minimized) { this.WindowState = FormWindowState.Minimized; } break; } } } private void Titlepanel_MouseDown(object sender, MouseEventArgs e) { if (this.WindowState == FormWindowState.Maximized) { return; } //Titlepanel.Cursor = Cursors.NoMove2D; oldMousePosition = e.Location; moving = true; } private void Titlepanel_MouseUp(object sender, MouseEventArgs e) { //Titlepanel.Cursor = Cursors.Default; moving = false; } private void Titlepanel_MouseMove(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && moving) { Point newPosition = new Point(e.Location.X - oldMousePosition.X, e.Location.Y - oldMousePosition.Y); this.Location += new Size(newPosition); } } private void Titlepanel_DoubleClick(object sender, EventArgs e) { if (titlepanel.Contains(button2)) { button2.PerformClick(); } } private void titlepanel_ControlRemoved(object sender, ControlEventArgs e) { switch (e.Control.Name) { case "button2": { if (titlepanel.Contains(button3)) { button3.Left = button1.Left - button1.Width; } break; } } } private void titlepanel_ControlAdded(object sender, ControlEventArgs e) { switch (e.Control.Name) { case "button2": { if (titlepanel.Contains(button3)) { button3.Left = button2.Left - button2.Width; } break; } case "button3": { if (titlepanel.Contains(button2)) { button3.Left = button2.Left - button2.Width; } break; } } } } }
以下是系统自动生成的代码:
代码中FormBorderStyle覆盖父类的同名属性,主要是实现根据不同的窗体,能够自动调整标题栏按钮,因为当FormBorderStyle为FormBorderStyle.Sizable或FormBorderStyle.SizableToolWindow时,才需要最大化按钮,否则都是不需要的。不需要的情况下,将移除最大化按钮对象button2,
titlepanel.Controls.Remove(button2);
由于隐藏自带的标题栏需要确保Text属性为空,ControlBox为False,所以我这里采取了重写这两个属性,并加上Browsable(false),让其在编辑器中不可见。
Title,TitleFont,TitleColor,TitleBarBackColor为新增自定义属性,分别用于设置标题文字,标题文字样式,标题文字颜色,标题栏背景色。
重写MaximizeBox与MinimizeBox两个属性,使其根据设为True与False时,能相应的调整标题栏按钮。
私有方法:ResetTitlePanel,用于重设标题栏按钮属性。
方法Titlebutton_Click这个简单,主要用于实现标题栏上三个按钮点击时所要执行的操作。
Titlepanel_MouseDown,Titlepanel_MouseUp ,Titlepanel_MouseMove 三个方法是用于实现点击鼠标右键并按住移动就能够移动窗体,Titlepanel_DoubleClick方法是实现双击时能够最大化或还原窗体功能。
最后的titlepanel_ControlRemoved与titlepanel_ControlAdded,实现的功能是当增加或移除按钮时,调整按钮的位置。
三、使用自定义窗体类
使用就比较简单了,先是新增一个窗体,然后将窗体类的父类由Form改为自定义窗体类(ZForm)即可,然后再切换到设计视图页面,是不是发现界面已经变化了呢,这时候就可以依据的想法灵活设置窗体标题栏样式,如下图:
public partial class Form1 : ZControls.ZForm { public Form1() { InitializeComponent(); } }
将MaximizeBox设为False时,运行的效果,是不是有点爽啊!
好了,都说完了,其实也很简单,我相信大部份高手都是不屑一看的,但此处只是作为一个学习与参考,可能大家有更好的方法,欢迎大家交流,共同进步。
最后我上传源码,仅大家参考与改进:
——
本文转自 梦在旅途 博客园博客,原文链接: http://www.cnblogs.com/zuowj/p/4133574.html ,如需转载请自行联系原作者