zoukankan      html  css  js  c++  java
  • Winform自定义窗体样式,实现标题栏可灵活自定义

    最近在编写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;
                        }
                }
            }
    
        }
    }

    以下是系统自动生成的代码:

    namespace ZControls
    {
        partial class ZForm
        {
            /// <summary>
            /// 必需的设计器变量。
            /// </summary>
            private System.ComponentModel.IContainer components = null;
    
            /// <summary>
            /// 清理所有正在使用的资源。
            /// </summary>
            /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
    
            #region Windows 窗体设计器生成的代码
    
            /// <summary>
            /// 设计器支持所需的方法 - 不要
            /// 使用代码编辑器修改此方法的内容。
            /// </summary>
            private void InitializeComponent()
            {
                this.titlepanel = new System.Windows.Forms.Panel();
                this.titlelabel = new System.Windows.Forms.Label();
                this.button3 = new System.Windows.Forms.Button();
                this.button2 = new System.Windows.Forms.Button();
                this.button1 = new System.Windows.Forms.Button();
                this.titlepanel.SuspendLayout();
                this.SuspendLayout();
                // 
                // titlepanel
                // 
                this.titlepanel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
                this.titlepanel.Controls.Add(this.titlelabel);
                this.titlepanel.Controls.Add(this.button3);
                this.titlepanel.Controls.Add(this.button2);
                this.titlepanel.Controls.Add(this.button1);
                this.titlepanel.Dock = System.Windows.Forms.DockStyle.Top;
                this.titlepanel.Location = new System.Drawing.Point(0, 0);
                this.titlepanel.Margin = new System.Windows.Forms.Padding(0);
                this.titlepanel.Name = "titlepanel";
                this.titlepanel.Size = new System.Drawing.Size(468, 30);
                this.titlepanel.TabIndex = 0;
                this.titlepanel.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.titlepanel_ControlAdded);
                this.titlepanel.ControlRemoved += new System.Windows.Forms.ControlEventHandler(this.titlepanel_ControlRemoved);
                this.titlepanel.DoubleClick += new System.EventHandler(this.Titlepanel_DoubleClick);
                this.titlepanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Titlepanel_MouseDown);
                this.titlepanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Titlepanel_MouseMove);
                this.titlepanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Titlepanel_MouseUp);
                // 
                // titlelabel
                // 
                this.titlelabel.AutoSize = true;
                this.titlelabel.Location = new System.Drawing.Point(12, 9);
                this.titlelabel.Name = "titlelabel";
                this.titlelabel.Size = new System.Drawing.Size(0, 12);
                this.titlelabel.TabIndex = 3;
                // 
                // button3
                // 
                this.button3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Right)));
                this.button3.Font = new System.Drawing.Font("微软雅黑 Light", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.button3.Location = new System.Drawing.Point(399, 4);
                this.button3.Name = "button3";
                this.button3.Size = new System.Drawing.Size(23, 23);
                this.button3.TabIndex = 2;
                this.button3.Tag = "min";
                this.button3.Text = "-";
                this.button3.UseVisualStyleBackColor = true;
                this.button3.Click += new System.EventHandler(this.Titlebutton_Click);
                // 
                // button2
                // 
                this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Right)));
                this.button2.Font = new System.Drawing.Font("微软雅黑 Light", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.button2.Location = new System.Drawing.Point(421, 4);
                this.button2.Name = "button2";
                this.button2.Size = new System.Drawing.Size(23, 23);
                this.button2.TabIndex = 1;
                this.button2.Tag = "max";
                this.button2.Text = "";
                this.button2.UseVisualStyleBackColor = true;
                this.button2.Click += new System.EventHandler(this.Titlebutton_Click);
                // 
                // button1
                // 
                this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
                | System.Windows.Forms.AnchorStyles.Right)));
                this.button1.Font = new System.Drawing.Font("微软雅黑 Light", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                this.button1.Location = new System.Drawing.Point(442, 4);
                this.button1.Name = "button1";
                this.button1.Size = new System.Drawing.Size(23, 23);
                this.button1.TabIndex = 0;
                this.button1.Tag = "close";
                this.button1.Text = "X";
                this.button1.UseVisualStyleBackColor = true;
                this.button1.Click += new System.EventHandler(this.Titlebutton_Click);
                // 
                // ZForm
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.ClientSize = new System.Drawing.Size(468, 246);
                this.ControlBox = false;
                this.Controls.Add(this.titlepanel);
                this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
                this.MaximizeBox = false;
                this.Name = "ZForm";
                this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
                this.titlepanel.ResumeLayout(false);
                this.titlepanel.PerformLayout();
                this.ResumeLayout(false);
    
            }
    
            #endregion
    
            private System.Windows.Forms.Panel titlepanel;
            private System.Windows.Forms.Button button3;
            private System.Windows.Forms.Button button2;
            private System.Windows.Forms.Button button1;
            private System.Windows.Forms.Label titlelabel;
        }
    }
    View Code

    代码中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时,运行的效果,是不是有点爽啊!

    好了,都说完了,其实也很简单,我相信大部份高手都是不屑一看的,但此处只是作为一个学习与参考,可能大家有更好的方法,欢迎大家交流,共同进步。

    最后我上传源码,仅大家参考与改进:

    Demo

    ——

  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/zuowj/p/4133574.html
Copyright © 2011-2022 走看看