C#中关于WinForm中重绘TabControl选项卡标题的问题

2024-01-08 09:58

本文主要是介绍C#中关于WinForm中重绘TabControl选项卡标题的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

      这里说的是每个TabPage的头部,也就是标题,不是工作区域。

      最开始用到TabControl的时候,我的每个选项卡是写死的,而后由于项目需求又动态添加了TabControl并生成各个选项卡,而两次我都要重绘

题,因此在这里把我当时两种情形下重绘的方法通过一个例子一起分享出来。

     首先先在窗体拖个Tabcontrol控件,然后更改了其Alignment属性为Left,使其选项卡在左边。然后可以通过更改其ItemSize调节每个选项卡的大

小。值得注意的是,因为在此是把TabControl向左旋转了90°,所以此时设置宽的时候实际上改变的是它的高,设置高的时候实际上改变的是它的

宽。而且设置宽(改变高)发现无效是因为受选项卡文本字体所影响,可相应地改变字体尺寸。调整一番后的效果图:


    接着就要进入正题重绘其选项卡背景了。首先要把它的DrawMode属性改为OwnerDrawFixed,改了这个才会让用户自己绘制标题生效。接着给

添加DrawItem事件。事件重绘方法如下:

复制代码
 1 private void tabMain_DrawItem(object sender, DrawItemEventArgs e)
 2         {
 3             Bitmap b0 = new Bitmap(@"..\..\Images\1.jpg");
 4             Bitmap b1 = new Bitmap(@"..\..\Images\2.jpg");
 5             Bitmap b2 = new Bitmap(@"..\..\Images\3.jpg");
 6             Bitmap b3 = new Bitmap(@"..\..\Images\4.jpg");
 7             switch (e.Index)
 8                 {
 9                     case 0:
10                         e.Graphics.DrawImage(b0, e.Bounds);
11                         break;
12                     case 1:
13                         e.Graphics.DrawImage(b1, e.Bounds);
14                         break;
15                     case 2: 
16                         e.Graphics.DrawImage(b2, e.Bounds);
17                         break;
18                     case 3:
19                         e.Graphics.DrawImage(b3, e.Bounds);
20                         break;
21                 }
22         }
复制代码

 本文的图片我都事先放在当前项目下的一个Images文件夹里了。

最终效果图:

     以上是写死的情况下为其重绘标题,现在来介绍当选项卡是动态生成时为其重绘标题的方法。在说明此之前,我们先为原有TabControl添

SelectedIndexChanged事件,通过获取其SelectedIndex从而知道哪个选项卡被点击了,在此,我在第二个选项卡里面动态添加另一个

TabControl并生成其各个TabPage。代码如下:

复制代码
 1 private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
 2         {
 3             switch (tabMain.SelectedIndex)
 4             {
 5                 case 0:
 6                     break;
 7                 case 1:
 8                         //假设动态生成的TabControl有4个选项卡
 9                     for (int i = 0; i < 4; i++)
10                     {
11                         TabPage page = new TabPage();
12                         page.Name = "page" + i.ToString();
13                         page.Text = (i + 1).ToString();
14                         this.tabSub.Controls.Add(page);
15                     }
16                     this.tabSub.ItemSize = new System.Drawing.Size(80, 80);
17                     this.tabSub.Font = new System.Drawing.Font("宋体", 20);
18                     this.tabSub.Dock = DockStyle.Fill;
19                     this.tabMain.TabPages[1].Controls.Add(tabSub);
20                     break;
21                 case 2:
22                     break;
23                 case 3:
24                     break;
25             }
26         }
复制代码

在外部预先定义好要生成的TabControl变量:

TabControl tabSub = new TabControl();

 效果如下:

好了,接下来也该为它重绘下标题了。首先在上面设置tabSub属性的代码下新增这两行:

this.tabSub.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.tabSub_DrawItem);
this.tabSub.DrawMode = System.Windows.Forms.TabDrawMode.OwnerDrawFixed;

第一行是为tabSub新增绘制标题的事件,第二行是为了让系统使用我们自己绘制的样式。

然后自己写个绘制方法,代码如下:

复制代码
 1 private void tabSub_DrawItem(object sender, DrawItemEventArgs e)
 2         {
 3             List<string> imgPath = new List<string>()
 4             { 
 5                 @"..\..\Images\d.jpg", 
 6                 @"..\..\Images\s.jpg", 
 7                 @"..\..\Images\n.jpg",
 8                 @"..\..\Images\x.jpg" 
 9             };
10             for (int i = 0; i < this.tabSub.TabCount; i++)
11             {
12                 Bitmap b = new Bitmap(imgPath[i]);
13                 if (e.Index == i)
14                 {
15                     e.Graphics.DrawImage(b, e.Bounds);
16                 }
17             }
18         }
复制代码

效果如下:

OK,至此大功告成。当然上述代码是有缺陷的,当你轮换左边选项卡最后又点到第二个选项卡时,它会再加载多一次,这个只需要在当初绘制的时

候加个判断就行了,可以判断当前选项卡下是否已经包含了这些控件,或者定义个布尔变量用来判断是否已经加载就可以了。





这篇关于C#中关于WinForm中重绘TabControl选项卡标题的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

C#解析JSON数据全攻略指南

《C#解析JSON数据全攻略指南》这篇文章主要为大家详细介绍了使用C#解析JSON数据全攻略指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、为什么jsON是C#开发必修课?二、四步搞定网络JSON数据1. 获取数据 - HttpClient最佳实践2. 动态解析 - 快速

Python错误AttributeError: 'NoneType' object has no attribute问题的彻底解决方法

《Python错误AttributeError:NoneTypeobjecthasnoattribute问题的彻底解决方法》在Python项目开发和调试过程中,经常会碰到这样一个异常信息... 目录问题背景与概述错误解读:AttributeError: 'NoneType' object has no at

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤