文章目录
  • 需求来源
  • 实现思路
  • 实施
  • 请看VCR
  • 等等别走,有优化


需求来源

需要在鼠标浮动到指定位置后提示出详细的信息,一开始使用的tooltip实现,但是里面的内容效果并不理想,需要有条理性,于是就想到能不能将展示的东西分列。

实现思路

使用两个字符串数据接收通过字符串切割后的内容,然后通过在tooltip的draw事件绘制时将内容分为两次绘制。

实施

自定封装一个ToolTip控件,继承ToolTIp然后添加两个事件,分别时Draw Popup DrawPopup 这两个事件在 ToolTip 类中扮演着重要的角色,用于自定义工具提示的显示和绘制。

Draw 事件在工具提示需要绘制时触发。通过处理这个事件,可以自定义工具提示的外观和内容。

  • 作用
  • 自定义绘制工具提示:在处理 Draw 事件时,可以完全控制工具提示的绘制,包括背景颜色、边框、文本内容和文本样式等。
  • 实现高级图形效果:可以使用 Graphics 对象来实现复杂的绘制效果,比如渐变色、图片、各种形状等。
  • 使用场景
  • 当默认的工具提示外观不能满足需求时,可以通过 Draw 事件自定义绘制工具提示。
  • 需要在工具提示中显示非文本内容(如图像、图表)时,可以在 Draw 事件中实现。

Popup 事件在工具提示显示之前触发。通过处理这个事件,可以动态调整工具提示的大小和内容。

  • 作用
  • 动态调整工具提示大小:在处理 Popup 事件时,可以根据内容的大小动态设置工具提示的尺寸,以确保内容完全显示。
  • 准备绘制环境:可以在 Popup 事件中进行一些准备工作,比如计算文本的最大宽度和高度,为后续的 Draw 事件做准备。
  • 使用场景
  • 需要根据内容动态调整工具提示的大小时,可以在 Popup 事件中进行计算和设置。
  • 需要在工具提示显示前进行一些准备工作,比如加载图片、计算文本尺寸等,可以在 Popup 事件中处理。
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Test1
{
    // 自定义工具提示类,继承自 ToolTip
    public class CustomToolTip : ToolTip
    {
        private string[] Column1; // 用于存储第一列的文本数组
        private string[] Column2; // 用于存储第二列的文本数组
        private Font TextFont; // 工具提示文本的字体
        // 记录第一列的宽度
        private int Column1MaxWidth = 0;
		
        // 构造函数,初始化自定义工具提示
        public CustomToolTip()
        {
            TextFont = new Font("微软雅黑", 15.0f); // 设置字体为“微软雅黑”,大小为15
            this.OwnerDraw = true; // 启用自定义绘制工具提示
            this.Draw += new DrawToolTipEventHandler(OnDraw); // 订阅 Draw 事件
            this.Popup += new PopupEventHandler(OnPopup); // 订阅 Popup 事件
        }

        // 设置工具提示的内容,将其拆分为两列
        public void SetContent(string content)
        {
            var parts = content.Split(new string[] { "," }, StringSplitOptions.None); // 按逗号拆分内容
            int midPoint = (parts.Length + 1) / 2; // 计算拆分成两列的中间点

            Column1 = new string[midPoint]; // 初始化第一列数组
            Column2 = new string[parts.Length - midPoint]; // 初始化第二列数组

            // 填充列数组
            for (int i = 0; i < parts.Length; i++)
            {
                if (i < midPoint)
                {
                    Column1[i] = parts[i];
                }
                else
                {
                    Column2[i - midPoint] = parts[i];
                }
            }
        }

        // 自定义工具提示的绘制事件处理程序
        private void OnDraw(object sender, DrawToolTipEventArgs e)
        {
            e.DrawBackground(); // 绘制工具提示的背景
            e.DrawBorder(); // 绘制工具提示的边框

            Brush brush = Brushes.Black; // 用于绘制文本的画笔
            Rectangle rct2 = e.Bounds; // 工具提示的边界
            e.Graphics.FillRectangle(Brushes.Bisque, rct2); // 用浅橙色填充背景
            e.Graphics.DrawRectangle(Pens.DarkGray, new Rectangle(0, 0, rct2.Width - 1, rct2.Height - 1)); // 绘制边框

            // 绘制第一列文本
            for (int i = 0; i < Column1.Length; i++)
            {
                e.Graphics.DrawString(Column1[i], TextFont, brush, new PointF(5, i * 25));
            }

            // 绘制第二列文本
            for (int i = 0; i < Column2.Length; i++)
            {
                e.Graphics.DrawString(Column2[i], TextFont, brush, new PointF(Column1MaxWidth, i * 25));
            }
        }

        // 在工具提示显示之前计算其大小的事件处理程序
        private void OnPopup(object sender, PopupEventArgs e)
        {
            int Column2MaxWidth = 0; // 用于存储第二列的最大宽度
            int maxHeight = 0; // 用于存储工具提示的最大高度

            // 计算第一列的最大宽度和高度
            foreach (var text in Column1)
            {
                var sz = TextRenderer.MeasureText(text, TextFont);
                if (sz.Width > Column1MaxWidth)
                    Column1MaxWidth = sz.Width;
                maxHeight += sz.Height;
            }

            // 计算第二列的最大宽度
            foreach (var text in Column2)
            {
                var sz = TextRenderer.MeasureText(text, TextFont);
                if (sz.Width > Column2MaxWidth)
                    Column2MaxWidth = sz.Width;
            }

            // 确保高度适应两列中较高的一列
            maxHeight = Math.Max(maxHeight, Column2.Length * TextRenderer.MeasureText("A", TextFont).Height);
            e.ToolTipSize = new Size(Column1MaxWidth + Column2MaxWidth + 20, maxHeight + 30); // 设置工具提示大小,并添加一些间距
        }
    }
}
  • 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.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.

这里对字符串的分割是根据,来的,根据个人需要修改SetContent方法中切割字符,当然也可以封装一下,这里本人偷懒了。
下面是使用的方式,先在我们窗体中创建一个自定义的Tooltip对象,具体使用就是先设置SetContent方法将要显示的内容传递进去。最后将要tooltip关联的控件对象绑定就行了

private CustomToolTip custom = new CustomToolTip();
        private void Form1_Load(object sender, EventArgs e)
        {

            string aa = $"工作人员姓名:aaa,出勤地点:aaa333344445555555555," +
               $"工号:aaa,出勤时间:aaa," +
               $"手机:aaaaaaaa,本站时间:aaa," +
               $"站名:aaa,工作班制:aaa," +
               $"当前已工作时间:aaa,班制时长:aaa1111," +
               $"工作人员所属部门:aaa";
            custom.SetContent(aa);
             custom.SetToolTip(button1,aa);//这里传递第二个参数只要是字符串就行,因为在SetContent方法时已经设置好要显示的内容了。
        }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

请看VCR

日常开发记录分享——C#控件ToolTip实现分栏显示内容_前端

等等别走,有优化

鉴于上面我们使用的在From_Load方法中去使用自定义tip时调用SetToolTip时第二个参数传递有些冗余,这里把自定义的tip控件给优化了一下,优化虽小也是进步

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Test1
{
    // 自定义工具提示类,继承自 ToolTip
    public class CustomToolTip : ToolTip
    {
        private string[] Column1; // 用于存储第一列的文本数组
        private string[] Column2; // 用于存储第二列的文本数组
        private Font TextFont; // 工具提示文本的字体
        priavte Control ParentCtrl;//父窗体控件
        // 记录第一列的宽度
        private int Column1MaxWidth = 0;

        // 构造函数,初始化自定义工具提示
        public CustomToolTip()
        {
            TextFont = new Font("微软雅黑", 15.0f); // 设置字体为“微软雅黑”,大小为15
            this.OwnerDraw = true; // 启用自定义绘制工具提示
            this.Draw += new DrawToolTipEventHandler(OnDraw); // 订阅 Draw 事件
            this.Popup += new PopupEventHandler(OnPopup); // 订阅 Popup 事件
        }

        // 设置工具提示的内容,将其拆分为两列
        private void SetContent(string content)
        {
            var parts = content.Split(new string[] { "," }, StringSplitOptions.None); // 按逗号拆分内容
            int midPoint = (parts.Length + 1) / 2; // 计算拆分成两列的中间点

            Column1 = new string[midPoint]; // 初始化第一列数组
            Column2 = new string[parts.Length - midPoint]; // 初始化第二列数组

            // 填充列数组
            for (int i = 0; i < parts.Length; i++)
            {
                if (i < midPoint)
                {
                    Column1[i] = parts[i];
                }
                else
                {
                    Column2[i - midPoint] = parts[i];
                }
            }
        }

        // 自定义工具提示的绘制事件处理程序
        private void OnDraw(object sender, DrawToolTipEventArgs e)
        {
            e.DrawBackground(); // 绘制工具提示的背景
            e.DrawBorder(); // 绘制工具提示的边框

            Brush brush = Brushes.Black; // 用于绘制文本的画笔
            Rectangle rct2 = e.Bounds; // 工具提示的边界
            e.Graphics.FillRectangle(Brushes.Bisque, rct2); // 用浅橙色填充背景
            e.Graphics.DrawRectangle(Pens.DarkGray, new Rectangle(0, 0, rct2.Width - 1, rct2.Height - 1)); // 绘制边框

            // 绘制第一列文本
            for (int i = 0; i < Column1.Length; i++)
            {
                e.Graphics.DrawString(Column1[i], TextFont, brush, new PointF(5, i * 25));
            }

            // 绘制第二列文本
            for (int i = 0; i < Column2.Length; i++)
            {
                e.Graphics.DrawString(Column2[i], TextFont, brush, new PointF(Column1MaxWidth, i * 25));
            }
        }

        // 在工具提示显示之前计算其大小的事件处理程序
        private void OnPopup(object sender, PopupEventArgs e)
        {
            int Column2MaxWidth = 0; // 用于存储第二列的最大宽度
            int maxHeight = 0; // 用于存储工具提示的最大高度
            //设置将文本拆分两个数组,用于后期显示为两列---在这里通过tip控件自带的GetToolTip方法获取提示文本内容然后进行拆分初始化
			SetContent(this.GetToolTip(ParentCtrl));
            // 计算第一列的最大宽度和高度
            foreach (var text in Column1)
            {
                var sz = TextRenderer.MeasureText(text, TextFont);
                if (sz.Width > Column1MaxWidth)
                    Column1MaxWidth = sz.Width;
                maxHeight += sz.Height;
            }

            // 计算第二列的最大宽度
            foreach (var text in Column2)
            {
                var sz = TextRenderer.MeasureText(text, TextFont);
                if (sz.Width > Column2MaxWidth)
                    Column2MaxWidth = sz.Width;
            }

            // 确保高度适应两列中较高的一列
            maxHeight = Math.Max(maxHeight, Column2.Length * TextRenderer.MeasureText("A", TextFont).Height);
            e.ToolTipSize = new Size(Column1MaxWidth + Column2MaxWidth + 20, maxHeight + 30); // 设置工具提示大小,并添加一些间距
        }
    }
}
  • 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.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
private CustomToolTip custom ;
        public Form1()
        {
            InitializeComponent();
           
        }
        private void Form1_Load(object sender, EventArgs e)
        {
 			custom = new CustomToolTip(button1);
            string aa = $"工作人员姓名:aaa,出勤地点:aaa333344445555555555," +
               $"工号:aaa,出勤时间:aaa," +
               $"手机:aaaaaaaa,本站时间:aaa," +
               $"站名:aaa,工作班制:aaa," +
               $"当前已工作时间:aaa,班制时长:aaa1111," +
               $"工作人员所属部门:aaa";
            custom.SetToolTip(button1,aa);
        }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.