winform窗体、控件的简单封装,重做标题栏

news2024/10/7 12:25:08

1标题栏封装中使用了以下技术:

知识点:
1.父类、子类的继承;
2.窗体之间的继承;
3.自定义控件的绘制;
4.多线程在窗体间的应用;
5.窗体和控件的封装;
6.回调函数(委托);

效果展示

在这里插入图片描述

部分代码展示

	/// <summary>
    /// 标题栏
    /// </summary>
    public sealed partial class UcViewTitle : UserControl
    {

        /// <summary>
        /// 鼠标按下时子控件、父控件的位置
        /// </summary>
        private Point _mouseDownChildLocation, _mouseDownParentLocation;

        /// <summary>
        /// 标题栏文本字体
        /// </summary>
        public Font TitleFont { get; set; } = new Font("微软雅黑", 24.25F, FontStyle.Regular, GraphicsUnit.Point, 134);

        /// <summary>
        /// 标题栏文本内容
        /// </summary>
        public string Title { get; set; } = "科技未来,等你引领";

        /// <summary>
        /// 标题栏背景颜色
        /// </summary>
        public Color TitleBackColor { get; set; } = Color.FromArgb(0, 49, 71);

        /// <summary>
        /// 标题栏文本颜色
        /// </summary>
        public Color TitleTextBackColor { get; set; } = Color.White;

        /// <summary>
        /// 回调函数:关闭窗体时触发
        /// </summary>
        public Action CallbackCloseForm;

        /// <summary>
        /// 鼠标双击时设置窗体最大化、默认状态
        /// </summary>
        public Func<FormWindowState> FunGetFormState;

        /// <summary>
        /// 鼠标双击时设置窗体最大化、默认状态
        /// </summary>
        public Action<FormWindowState> ActionMouseDouble;

        /// <summary>
        /// 鼠标按下时窗体的位置
        /// </summary>
        public Func<Point> ActionMouseDownLocation;

        /// <summary>
        /// 鼠标移动后窗体的新位置
        /// </summary>
        public Action<Point> ActionMouseMoveLocation;

        /// <summary>
        /// 构造函数
        /// </summary>
        public UcViewTitle()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
            SetToolTip();
        }

        private void UcViewTitle_Load(object sender, EventArgs e)
        {
            new Task(() =>
            {
                try
                {
                    while (true)
                    {
                        Thread.Sleep(1000);
                        Invoke(new EventHandler(delegate { this.Refresh(); }));
                    }
                }
                catch (Exception ex)
                {


                }
            }).Start();
        }


        [Description("跟随串口大小重新绘制标题栏")]
        private void UcTitle_SizeChanged(object sender, EventArgs e)
        {
            pic_Close.Location = new Point(this.Width - 5 - pic_Close.Width, this.Height / 2 - pic_Close.Height / 2);
            pic_Maximize.Location = new Point(pic_Close.Location.X - 5 - pic_Minimality.Width, this.Height / 2 - pic_Maximize.Height / 2);
            pic_Minimality.Location = new Point(pic_Maximize.Location.X - 5 - pic_Minimality.Width, this.Height / 2 - pic_Close.Height / 2);
            //pic_Logo.Location = new Point(10, this.Height / 2 - pic_Logo.Height / 2);
            SetPictureMaxIcon();
            Refresh();
        }

        [Description("绘制标题栏")]
        private void UcTitle_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(TitleBackColor);
            // e.Graphics.Clear(Color.FromArgb(14, 30, 63));
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;//指定抗锯齿的呈现

            var brush = new SolidBrush(TitleTextBackColor);

            #region [绘制日期时间]

            var textTimeStartX = pic_Logo.Location.X + pic_Logo.Width + 10;
            var textTimeFont = new Font(TitleFont.Name, 14f, FontStyle.Regular, GraphicsUnit.Point, 134);

            string text = GetDate();
            var textDateSize = e.Graphics.MeasureString(text, textTimeFont);
            PointF textLocation = new PointF(textTimeStartX, this.Height / 2);
            e.Graphics.DrawString(text, textTimeFont, brush, textLocation);

            text = GetTime();
            var textTimeSize = e.Graphics.MeasureString(text, textTimeFont);
            textLocation = new PointF(textTimeStartX + textDateSize.Width / 2 - textTimeSize.Width / 2, this.Height / 2 - textDateSize.Height);
            e.Graphics.DrawString(text, textTimeFont, brush, textLocation);
            #endregion [绘制日期时间]

            //绘制标题
            var textTitleSize = e.Graphics.MeasureString(Title, TitleFont);
            textLocation = new PointF(this.Width / 2.0f - textTitleSize.Width / 2.0f, this.Height / 2.0f - textTitleSize.Height / 2.0f);
            e.Graphics.DrawString(Title, TitleFont, brush, textLocation);

        }

        [Description("最小化窗口")]
        private void pic_Minimality_Click(object sender, EventArgs e) => ActionMouseDouble?.Invoke(FormWindowState.Minimized);

        [Description("最大化窗口")]
        private void pic_Maximize_Click(object sender, EventArgs e) => SwitchWindowState();

        [Description("关闭窗口")]
        private void pic_Close_Click(object sender, EventArgs e) => CallbackCloseForm?.Invoke();

        [Description("鼠标双击时设置窗体最大化、默认状态")]
        private void UcViewTitle_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            SwitchWindowState();
        }

        [Description("鼠标按下记录位置信息用于计算移动窗口的初始值")]
        private void UcViewTitle_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _mouseDownChildLocation = e.Location;
            }
        }

        [Description("鼠标按下并移动时设置窗口新的位置信息")]
        private void UcViewTitle_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ActionMouseDouble?.Invoke(FormWindowState.Normal);
                if (ActionMouseDownLocation != null)
                {
                    _mouseDownParentLocation = ActionMouseDownLocation();
                }
                var addX = e.X - _mouseDownChildLocation.X;
                var addY = e.Y - _mouseDownChildLocation.Y;
                ActionMouseMoveLocation?.Invoke(new Point(_mouseDownParentLocation.X + addX, _mouseDownParentLocation.Y + addY));
            }
        }

        [Description("设置最小化、最大化、关闭的鼠标悬空提示信息")]
        private void SetToolTip()
        {
            new ToolTip().SetToolTip(pic_Minimality, "最小化");
            new ToolTip().SetToolTip(pic_Maximize, "最大化");
            new ToolTip().SetToolTip(pic_Close, "关闭");
        }

        [Description("鼠标双击时设置窗体最大化、默认状态")]
        private void SwitchWindowState()
        {
            if (FunGetFormState != null)
            {
                var state = FunGetFormState();
                state = state == FormWindowState.Maximized
                    ? FormWindowState.Normal
                    : FormWindowState.Maximized;
                ActionMouseDouble?.Invoke(state);
                SetPictureMaxIcon();
            }
        }

        [Description("设置最大化图标")]
        private void SetPictureMaxIcon()
        {
            if (FunGetFormState == null) return;

            var state = FunGetFormState();
            switch (state)
            {
                case FormWindowState.Normal:
                    pic_Maximize.BackgroundImage = Resources.FormTitle_最大化1;
                    break;
                default:
                    pic_Maximize.BackgroundImage = Resources.FormTitle_最大化;
                    break;
            }
        }

        /// <summary>
        /// 获取时间串(格式:2008年08月08日 10:20:06)
        /// </summary>
        /// <returns></returns>
        private string GetDate()
        {
            DateTime ts = DateTime.Now;
            var str = new StringBuilder();
            str.Append($"{ts.Year}年");
            str.Append($"{ts.Month.ToString().PadLeft(2, '0')}月");
            str.Append($"{ts.Day.ToString().PadLeft(2, '0')}日");
            return str.ToString();
        }
        /// <summary>
        /// 获取时间串(格式:10:20:06)
        /// </summary>
        /// <returns></returns>
        private string GetTime()
        {
            DateTime ts = DateTime.Now;
            var str = new StringBuilder();
            str.Append($"{ts.Hour.ToString().PadLeft(2, '0')}:");
            str.Append($"{ts.Minute.ToString().PadLeft(2, '0')}:");
            str.Append($"{ts.Second.ToString().PadLeft(2, '0')}");
            return str.ToString();
        }

        /// <summary>
        /// 设置LOGO
        /// </summary>
        /// <param name="bmp">LOGO图像</param>
        /// <param name="logoWidth">LOGO的宽度</param>
        public void SetLogo(Bitmap bmp, int logoWidth)
        {
            pic_Logo.Visible = true;
            pic_Logo.BackgroundImage = bmp;
            pic_Logo.Width = logoWidth;
        }
    }

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

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

相关文章

OpenCV入门2——图像视频的加载与展示一些API

文章目录 题目OpenCV创建显示窗口OpenCV加载显示图片题目 OpenCV保存文件利用OpenCV从摄像头采集视频从多媒体文件中读取视频帧将视频数据录制成多媒体文件OpenCV控制鼠标关于[np.uint8](https://stackoverflow.com/questions/68387192/what-is-np-uint8) OpenCV中的TrackBar控…

探索人工智能领域——每日30个名词详解【day3】

目录 前言 正文 总结 &#x1f308;嗨&#xff01;我是Filotimo__&#x1f308;。很高兴与大家相识&#xff0c;希望我的博客能对你有所帮助。 &#x1f4a1;本文由Filotimo__✍️原创&#xff0c;首发于CSDN&#x1f4da;。 &#x1f4e3;如需转载&#xff0c;请事先与我联系以…

【C++初阶】STL详解(一)string类

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

春秋云境靶场CVE-2022-25578漏洞复现(利用htaccess文件进行任意文件上传)

文章目录 前言一、CVE-2022-25578靶场概述二、CVE-2022-25578复现需要知道的知识点1、什么是htaccess文件2、上传htaccess文件的条件是什么&#xff1f;3、htaccess文件的作用是什么&#xff1f; 三、CVE-2022-32991漏洞复现1、信息收集2、找上传点3、上传后蚁剑连接getshell 总…

vmware安装MacOS以及flutter遇到的问题

安装过程&#xff1a;参考下面的文章 链接&#xff1a; 虚拟机VMware安装苹果系统macOS&#xff0c;超级详细教程&#xff0c;附文件下载&#xff0c;真教程&#xff01;&#xff01; 无限重启情况&#xff1a; &#xff08;二&#xff09; 配置虚拟机找到你的虚拟机安装文件…

氢原子波函数等概率面的绘制

氢原子波函数等概率面的绘制 归一化后的氢原子波函数

如何解决3d max渲染效果图全白这类异常问题?

通过3d max渲染效果图时&#xff0c;经常会出现3Dmax渲染效果图全黑或是3Dmax渲染效果图全白这类异常问题。可能遇到这类问题较多的都是新手朋友。不知如何解决。 3dmax渲染出现异常的问题&#xff0c;该如何高效解决呢&#xff1f;今天小编这里整理几项知识点&#xff0c;大家…

数据结构与算法【递归】Java实现

递归 递归是一种解决计算问题的方法&#xff0c;其中解决方案取决于同一类问题的更小子集。 特点&#xff1a; 自己调用自己&#xff0c;如果说每个函数对应着一种解决方案&#xff0c;自己调用自己意味着解决方案是一样的&#xff08;有规律的&#xff09;每次调用&#xf…

在 Rocky 中使用 FreeRDP 远程连接 Windows 机器

前言&#xff1a; 远程控制已成为 IT 人员和企业用户在处理日常任务时不可或缺的工具。无论是进行系统管理、支持远程工作&#xff0c;还是协助解决技术问题&#xff0c;一个可靠且高效的远程桌面工具都是业务连续性的关键。开始我个人使用了todesk&#xff08;也曾鲜想过向日…

Google 向中国开发者开放数百份 TensorFlow 资源

Google 的机器学习框架 TensorFlow 自 2015 年开源后&#xff0c;已然成为 AI 领域最受欢迎的框架。 据统计&#xff0c;在广受欢迎的 Python 编程语言在线软件知识库 PyPi 上&#xff0c;TensorFlow 的下载次数已超过 90 万&#xff0c;其中有 15% 来自中国。谷歌官方博客也表…

电脑篇——将串口映射到远程电脑上

通过Windows自带的远程桌面连接功能&#xff0c;可以通过修改本地资源选项&#xff0c;将本机的串口/端口映射到远程电脑上。 即可将端口映射到远程电脑上。 &#xff08;在远程的电脑的设备管理器中可能不会显示&#xff0c;但是用串口调试相关的工具&#xff0c;是可以找到相…

算法笔记-第九章-二叉树的遍历(未完成-还要搞)

算法笔记-第九章-二叉树的遍历 二叉树的先序遍历二叉树的中序遍历二叉树的后序遍历二叉树的层次遍历注意点一&#xff1a;注意点二&#xff1a; 二叉树的高度二叉树的结点层号翻转二叉树翻转二叉树不同的方法方法一&#xff1a;用栈实现方法二&#xff1a;用队列实现方法三&…

深度学习之基于Pytorch和OCR的识别文本检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介深度学习与OCRPyTorch在OCR中的应用文本检测系统的关键组成部分1. 图像预处理2. 深度学习模型3. 文本检测算法4. 后处理 二、功能三、系统四. 总结 一项目简…

git clone:SSL: no alternative certificate subject name matches target host name

git clone 时的常见错误&#xff1a; fatal: unable to access ‘https://ip_or_domain/xx/xx.git/’: SSL: no alternative certificate subject name matches target host name ‘ip_or_domain’ 解决办法&#xff1a; disable ssl verify git config --global http.sslVe…

基于 Amazon EKS 搭建开源向量数据库 Milvus

一、前言 生成式 AI&#xff08;Generative AI&#xff09;的火爆引发了广泛的关注&#xff0c;也彻底点燃了向量数据库&#xff08;Vector Database&#xff09;市场&#xff0c;众多的向量数据库产品开始真正出圈&#xff0c;走进大众的视野。 根据 IDC 的预测&#xff0c;…

基于STC12C5A60S2系列1T 8051单片机的数模芯片TLC5615实现数模转换应用

基于STC12C5A60S2系列1T 8051单片的数模芯片TLC5615实现数模转换应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍数模芯片TLC5615介绍通过按键调节数模芯片TLC5615…

低代码编辑平台后台实现

背景 之前做过一个前端低代码编辑平台&#xff0c;可以实现简单的移动端页面组件拖拽编辑&#xff1a; https://github.com/li-car-fei/react-visual-design 最近基于C的oatpp框架实现了一下后台。使用oatpp框架做web后台开发时&#xff0c;发现按照官方的示例使用的话&#…

SSH远程登录协议

目录 什么是ssh服务器 概念 优点 原理 SSH登录 方法一 无需验证 方法二 格式&#xff1a; ssh -l 用户名 IP 地址 -p port -l &#xff1a;指定登录名称 -p&#xff1a;选项&#xff0c;指定登录端口&#xff08;当服务端的端口非默认时&#xff0c;需要使用-p…

拿到信创天翼云电脑账号后,我又傻眼了...

在《面向国产系统的 App 发布&#xff0c;含泪总结》中&#xff0c;我就吐槽过信创产品的不靠谱。用户购买一台终端&#xff0c;都没法用&#xff0c;得经历复杂的账号申请。 紧催慢催&#xff0c;等待了半个月之后&#xff0c;今天终于拿到了账号。然而&#xff0c;满怀期待登…

OpenAI与微软合作,构建 ChatGPT 5 模型;10天准确天气预报

&#x1f989; AI新闻 &#x1f680; OpenAI与微软合作&#xff0c;构建 ChatGPT 5 模型&#xff0c;下一代人工智能或拥有超级智能 摘要&#xff1a;OpenAI首席执行官 Sam Altman 在接受采访时表示&#xff0c;OpenAI正在与微软合作构建下一代人工智能模型 ChatGPT 5&#x…