WinForm中重绘TabControl选项卡标题

时间:2021-02-12 00:50:37

最近开发WinForm频繁使用了TabControl控件,这个控件的选项卡没有BackgroundImage这个属性,那么如何为其各个选项卡添加背景图片呢?(这里说的是每个TabPage的头部,也就是标题,不是工作区域。)

最开始用到TabControl的时候,我的每个选项卡是写死的,而后由于项目需求又动态添加了TabControl并生成各个选项卡,而两次我都要重绘其标题,因此在这里把我当时两种情形下重绘的方法通过一个例子一起分享出来。

首先先在窗体拖个Tabcontrol控件,然后更改了其Alignment属性为Left,使其选项卡在左边。然后可以通过更改其ItemSize调节每个选项卡的大小。值得注意的是,因为在此是把TabControl向左旋转了90°,所以此时设置宽的时候实际上改变的是它的高,设置高的时候实际上改变的是它的宽。而且设置宽(改变高)发现无效是因为受选项卡文本字体所影响,可相应地改变字体尺寸。调整一番后的效果图:

WinForm中重绘TabControl选项卡标题

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

 private void tabMain_DrawItem(object sender, DrawItemEventArgs e)
{
Bitmap b0 = new Bitmap(@"..\..\Images\1.jpg");
Bitmap b1 = new Bitmap(@"..\..\Images\2.jpg");
Bitmap b2 = new Bitmap(@"..\..\Images\3.jpg");
Bitmap b3 = new Bitmap(@"..\..\Images\4.jpg");
switch (e.Index)
{
case :
e.Graphics.DrawImage(b0, e.Bounds);
break;
case :
e.Graphics.DrawImage(b1, e.Bounds);
break;
case :
e.Graphics.DrawImage(b2, e.Bounds);
break;
case :
e.Graphics.DrawImage(b3, e.Bounds);
break;
}
}

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

最终效果图:
WinForm中重绘TabControl选项卡标题

以上是写死的情况下为其重绘标题,现在来介绍当选项卡是动态生成时为其重绘标题的方法。在说明此之前,我们先为原有TabControl添加SelectedIndexChanged事件,通过获取其SelectedIndex从而知道哪个选项卡被点击了,在此,我在第二个选项卡里面动态添加另一个TabControl并生成其各个TabPage。代码如下:

 private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
{
switch (tabMain.SelectedIndex)
{
case :
break;
case :
//假设动态生成的TabControl有4个选项卡
for (int i = ; i < ; i++)
{
TabPage page = new TabPage();
page.Name = "page" + i.ToString();
page.Text = (i + ).ToString();
this.tabSub.Controls.Add(page);
}
this.tabSub.ItemSize = new System.Drawing.Size(, );
this.tabSub.Font = new System.Drawing.Font("宋体", );
this.tabSub.Dock = DockStyle.Fill;
this.tabMain.TabPages[].Controls.Add(tabSub);
break;
case :
break;
case :
break;
}
}

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

TabControl tabSub = new TabControl();

效果如下:

WinForm中重绘TabControl选项卡标题

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

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

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

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

 private void tabSub_DrawItem(object sender, DrawItemEventArgs e)
{
List<string> imgPath = new List<string>()
{
@"..\..\Images\d.jpg",
@"..\..\Images\s.jpg",
@"..\..\Images\n.jpg",
@"..\..\Images\x.jpg"
};
for (int i = ; i < this.tabSub.TabCount; i++)
{
Bitmap b = new Bitmap(imgPath[i]);
if (e.Index == i)
{
e.Graphics.DrawImage(b, e.Bounds);
}
}
}

效果如下:
WinForm中重绘TabControl选项卡标题

OK,至此大功告成。当然上述代码是有缺陷的,当你轮换左边选项卡最后又点到第二个选项卡时,它会再加载多一次,这个只需要在当初绘制的时候加个判断就行了,可以判断当前选项卡下是否已经包含了这些控件,或者定义个布尔变量用来判断是否已经加载就可以了。

WinForm中重绘TabControl选项卡标题的更多相关文章

  1. C&num;重绘TabControl

    C#重绘TabControl的Tabpage标签,添加图片及关闭按钮 Code highlighting produced by Actipro CodeHighlighter (freeware)h ...

  2. C&num; 重绘tabControl,添加关闭按钮(页签)

    C# 重绘tabControl,添加关闭按钮(页签) 调用方法 参数: /// <summary> /// 初始化 /// </summary> /// <param n ...

  3. 在WPF窗体中重绘

    原文:在WPF窗体中重绘   写这篇主要是为了验证任何元素自身都具备绘图功能. 在默认Window中重写OnRender方法 protected override void OnRender(Draw ...

  4. 上传图片时,使用GDI&plus;中重绘方式将CMYK图片转为RGB图片

    原文:上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片 我们知道,如果网站上传图片时,如果用户上传的是CMYK图片,那么在网站上将是无法显示的,通常的现象是出现一个红叉.下面使用将Ima ...

  5. C&num; 重绘tabControl,添加关闭按钮(续)

    在上一篇随笔中,添加关闭按钮是可以实现 ,但细心一点就会发现,每次关闭一个选项卡,tableControl都会自动跳到第一个页面,显然 这不是我们想要的,为此,我修改了部分的代码.除此之外,我还添加了 ...

  6. 重绘TabControl

    本文转载自:http://blog.csdn.net/conmajia/article/details/7596718 作者:野比 (conmajia@gmail.com) 时间:May, 2012 ...

  7. 【转】VC的MFC中重绘函数的使用总结(整理)

    原文网址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html 在刷新窗口时经常要调用重绘函数MFC提供了三个函数用于窗口重绘Inva ...

  8. Winform 中DataGridView控件添加行标题

    有很多种方法. 1.可以在DataGridView控件中的RowStateChanged事件改变行标题单元格的值(Row.HeaderCell.Value) /// <summary> / ...

  9. C&num; 自定义重绘TabControl

    using System.Drawing; using System.Windows.Forms; using System.Drawing.Drawing2D; using System.Runti ...

随机推荐

  1. decimalFormat&lpar;&quot&semi;&num;&quot&semi;&comma;&quot&semi;&num;&num;0&period;00&quot&semi;&rpar; java

    importjava.text.DecimalFormat; publicclassTestNumberFormat{ publicstaticvoidmain(String[]args){ doub ...

  2. &lbrack;Tool&rsqb; 使用Visual Studio Code开发TypeScript

    [Tool] 使用Visual Studio Code开发TypeScript 注意 依照本篇操作步骤实作,就可以在「Windows」.「OS X」操作系统上,使用Visual Studio Code ...

  3. android 中文转拼音

    /** * 将汉字转换为拼音 * @author Champion.Wong * */ public class Trans2PinYin { private static int[] pyvalue ...

  4. STM32之串口通信

    一.RS232通信协议 1.概念 个人计算机上的通讯接口之一,由电子工业协会(Electronic Industries Association,EIA) 所制定的异步传输标准接口. 2.电气特性 逻 ...

  5. epoll&lpar;&rpar;无论涉及wait队列分析

    事件1. epfd-file->eventpoll->wq: struct eventpoll {     ...     wait_queue_head_t wq;     //用于ep ...

  6. c&plus;&plus;虚函数实现机制(转)

    前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有“多种形态”,这是一种泛 ...

  7. 1&period;3 Essential Python Libraries(一些重要的Python库)

    1.3 Essential Python Libraries(一些重要的Python库) 如果不了解Python的数据生态,以及本书中即将用到的一些库,这里会做一个简单的介绍: Numpy 这里就不过 ...

  8. 各种mac软件地址

    http://www.sdifenzhou.com/  各种软件地址

  9. hdu2579之BFS

    Dating with girls(2) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  10. iOS 11导航栏设置BarButtonItem变形问题和错位问题

    升级到 iOS 11,你可能会发现你的 App 的工具栏的行为出了点异常.比如奇点,我在使用过程中,发现工具栏时灵时不灵,感觉很难点到.这是怎么回事?通过 Xcode 的 Debug View Hie ...