【C#】WinForm自定义控件及窗体

发布于:2025-03-24 ⋅ 阅读:(24) ⋅ 点赞:(0)

前言

WinForm(Windows Forms)是Microsoft.NET框架中的技术,用于开发Windows桌面应用程序。它提供了一套丰富的控件和组件。通过拖放控件、编写事件处理程序等方式快速构建用户界面。

通过属性窗口定制这些控件的外观和行为。
通过数据绑定,将UI控件与数据源连接,实现数据的展示和更新。
通过上面的方法可以帮助开发者高效地创建桌面窗体应用程序,尤其适合初学者和需要快速开发的项目。

本文介绍了如何创建Winform窗体,并自定义窗体样式和窗体的基本功能。

1、窗体关闭、最大化、最小化、适应。
2、无边框窗体移动、调整窗体大小。
3、菜单展开折叠。

界面预览

在这里插入图片描述

代码

自定义按钮

用户自定义按钮:        

SelectedState:用户点击后状态取反。
Radius:按钮圆角半径。
HoverColor:鼠标悬停时的背景色。

public class UCButton : Button
{
    #region  公共字段、属性
    private bool _selectedState = false;

    [Category("UserProperty")]
    [Description("选中状态")]
    public bool SelectedState
    {
        get => _selectedState;
        private set
        {
            _selectedState = value;
            this.Invalidate();
        }
    }


    private int radius = 15;

    [Category("UserProperty")]
    [Description("圆角半径")]
    public int Radius
    {
        get { return radius; }
        set
        {
            radius = value;
            this.Invalidate();
        }
    }
    private Color _defaultColor;

    private Color _hoverColor = Color.LightBlue;

    [Category("UserProperty")]
    [Description("鼠标悬停时的背景色")]
    public Color HoverColor 
    { 
        get => _hoverColor; 
        set => _hoverColor = value; 
    }
    #endregion
    public UCButton()
    {
        Initialize();
    }
    private void Initialize()
    {
        this.DoubleBuffered = true;
        this.FlatStyle = FlatStyle.Flat;
        this.FlatAppearance.BorderSize = 0;
        this.SetStyle(ControlStyles.UserPaint
            | ControlStyles.AllPaintingInWmPaint
            | ControlStyles.OptimizedDoubleBuffer
            | ControlStyles.ResizeRedraw
            | ControlStyles.SupportsTransparentBackColor, true);
        _defaultColor = BackColor;

        this.MouseEnter += UCButton_MouseEnter;
        this.MouseLeave += UCButton_MouseLeave;
    }
    private void UCButton_MouseEnter(object sender, EventArgs e)
    {
        this.BackColor = HoverColor; // 鼠标进入时更改背景色
    }
    private void UCButton_MouseLeave(object sender, EventArgs e)
    {
        this.BackColor = _defaultColor; // 鼠标离开时恢复默认背景色
    }
    protected override void OnClick(EventArgs e)
    {
        base.OnClick(e);
        _selectedState = !_selectedState;
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;                     // 设置抗锯齿
        e.Graphics.CompositingQuality = CompositingQuality.HighQuality;         // 高质量合成
        e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;    // 高质量插值
        // 绘制圆角矩形
        using (GraphicsPath path = new GraphicsPath())
        {
            path.AddArc(0, 0, radius, radius, 180, 90);                         // 左上角
            path.AddArc(this.Width - radius, 0, radius, radius, 270, 90);       // 右上角
            path.AddArc(this.Width - radius, this.Height - radius, radius, radius, 0, 90);  // 右下角
            path.AddArc(0, this.Height - radius, radius, radius, 90, 90);                   // 左下角
            path.CloseFigure();

            this.Region = new Region(path); // 设置按钮的区域为圆角矩形
        }
        // 绘制按钮文本
        using (Brush brush = new SolidBrush(this.ForeColor))
        {
            SizeF textSize = e.Graphics.MeasureString(this.Text, this.Font);
            PointF textLocation = new PointF((this.Width - textSize.Width) / 2, (this.Height - textSize.Height) / 2);
            e.Graphics.DrawString(this.Text, this.Font, brush, textLocation);
        }
    }
}

窗体代码

1、窗体关闭、最大化、最小化、适应。
2、无边框窗体移动、调整窗体大小。
3、菜单展开折叠。

public partial class MainForm : Form
{
    private int ButtonWidth = 62;

    #region 窗体初始化、加载、关闭
    public MainForm()
    {
        InitializeComponent();
        this.CenterToParent();
        this.CenterToScreen();
    }
    private void MainForm_Load(object sender, System.EventArgs e)
    {
        WinMoveBinding(panel_TopBorderItem);
        WinMoveBinding(pic_WinIcon);
        this.WindowState = FormWindowState.Normal;
        this.MinimumSize = new System.Drawing.Size(150, 150);
        panel_MenuItemText.Hide();
        ButtonWidth = btn_Expand.Width;
    }
    private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    {

    }
    #endregion
    
    /// <summary>
    /// 窗体移动功能事件绑定
    /// </summary>
    private void WinMoveBinding(Control control)
    {
        control.MouseDown += topBorderPanel_MouseDown;
        control.MouseMove += topBorderPanel_MouseMove;
        control.MouseUp += topBorderPanel_MouseUp;
    }

    #region 窗体拖动
    private Point mouseOffset;
    private void topBorderPanel_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            mouseOffset = new Point(-e.X, -e.Y);
        }
    }

    private void topBorderPanel_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            Point mousePos = Control.MousePosition;
            mousePos.Offset(mouseOffset.X, mouseOffset.Y);
            this.Location = mousePos;
        }
    }

    private void topBorderPanel_MouseUp(object sender, MouseEventArgs e)
    {
        mouseOffset = Point.Empty;
    }
    #endregion

    #region 无边框窗体随意拖动和改变尺寸
    const int WM_NCHITTEST = 0x0084;
    const int HTLEFT = 10;
    const int HTRIGHT = 11;
    const int HTTOP = 12;
    const int HTTOPLEFT = 13;
    const int HTTOPRIGHT = 14;
    const int HTBOTTOM = 15;
    const int HTBOTTOMLEFT = 0x10;
    const int HTBOTTOMRIGHT = 17;
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        switch (m.Msg)
        {
            case WM_NCHITTEST:
                Point vPoint = new Point((int)m.LParam & 0xFFFF,
                    (int)m.LParam >> 16 & 0xFFFF);
                vPoint = PointToClient(vPoint);
                if (vPoint.X <= 5)
                    if (vPoint.Y <= 5)
                        m.Result = (IntPtr)HTTOPLEFT;
                    else if (vPoint.Y >= ClientSize.Height - 5)
                        m.Result = (IntPtr)HTBOTTOMLEFT;
                    else m.Result = (IntPtr)HTLEFT;
                else if (vPoint.X >= ClientSize.Width - 5)
                    if (vPoint.Y <= 5)
                        m.Result = (IntPtr)HTTOPRIGHT;
                    else if (vPoint.Y >= ClientSize.Height - 5)
                        m.Result = (IntPtr)HTBOTTOMRIGHT;
                    else m.Result = (IntPtr)HTRIGHT;
                else if (vPoint.Y <= 5)
                    m.Result = (IntPtr)HTTOP;
                else if (vPoint.Y >= ClientSize.Height - 5)
                    m.Result = (IntPtr)HTBOTTOM;
                break;
        }
    }
    #endregion

    #region 窗体关闭、最大化、最小化
    private void btn_ClosingWindow_Click(object sender, System.EventArgs e)
    {
        if (MessageBox.Show("是否关闭窗体!", "关闭", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
        {
            this.Close();
        }
    }

    private void btn_Maximize_Click(object sender, System.EventArgs e)
    {
        Button button = sender as Button;
        if (this.WindowState == FormWindowState.Maximized)
        {
            this.WindowState = FormWindowState.Normal;
            button.Image = global::ModbusDemo.Properties.Resources.maximize_blue_32;
        }
        else
        {
            this.WindowState = FormWindowState.Maximized;
            button.Image = global::ModbusDemo.Properties.Resources.restore_blue_32;

        }
    }

    private void btn_Minimize_Click(object sender, System.EventArgs e)
    {
        this.WindowState = FormWindowState.Minimized;
    }

    #endregion

    /// <summary>
    /// 折叠按钮
    /// </summary>
    private void btn_Expand_Click(object sender, System.EventArgs e)
    {
        //展开
        if (!btn_Expand.SelectedState)
        {
            btn_Expand.Image = global::ModbusDemo.Properties.Resources.collapse_left_blue_32;
            panel_MenuItemIcon.Width = ButtonWidth;
            panel_MenuItemText.ScrollControlIntoView(btn_Expand);
            panel_MenuItemText.Show();
            panel_LeftMenuItem.Width = 256;
        }
        //折叠
        else
        {
            btn_Expand.Image = global::ModbusDemo.Properties.Resources.collapse_right_blue_32;
            
            panel_MenuItemIcon.Width = ButtonWidth;
            panel_LeftMenuItem.Width = ButtonWidth;
            panel_MenuItemText.Hide();
        }
    }

    /// <summary>
    /// 首页按钮
    /// </summary>
    private void btn_Home_Click(object sender, EventArgs e)
    {

    }
}

结语

既是分享,也是备份。


网站公告

今日签到

点亮在社区的每一天
去签到