CSkin博客
标题: 【美化TabControl教程】仿苹果Safari浏览器选项卡 [打印本页]
作者: 乔克斯 时间: 2015-1-26 18:18
标题: 【美化TabControl教程】仿苹果Safari浏览器选项卡
一步一步玩控件:自定义TabControl——从山寨Apple Safari开始
教程:
分析,分析
山寨的灵魂在于分析,首先把刚才拍的高清果照扯过来分解了。
我把他分解成这几个部分:
- 这篇是#1-1,就专心讨论关于标签的东西,也就是第2、3点。
- 组件设计
- 分析了其中的功能,那么就要想想怎么来实现。
- 从功能来看,这个窗口实际上是由多个子面板切换来实现的,最多他加了点自动缩放。所以从本质来说,还是一个标签切换的窗口。
- 我最早想到的就是大名鼎鼎却又丑得无以复加的TabControl。
按照标签切换这个思想,TabControl完全可以胜任这次的山寨需求。但是TabControl这么丑,必须要给它整整容才行。想不到我竟然有整容的才华。
下手吧,年轻人!
因为要改动的地方会很多,所以还是完全自己来绘制标签好了。为了完全自定义TabControl,同时方便循环利用,从TabControl派生一个我们自己的标签控件TabControlEx。
[C#] 纯文本查看 复制代码
public class TabControlEx : System.Windows.Forms.TabControl
这就是我们的TabControlEx,看起来和TabControl没什么两样(那是当然的)。
为了让他看起来不太一样,在构造函数里加上下面的代码。
[C#] 纯文本查看 复制代码
base.SetStyle(
ControlStyles.UserPaint | // 控件将自行绘制,而不是通过操作系统来绘制
ControlStyles.OptimizedDoubleBuffer | // 该控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁
ControlStyles.AllPaintingInWmPaint | // 控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁
ControlStyles.ResizeRedraw | // 在调整控件大小时重绘控件
ControlStyles.SupportsTransparentBackColor, // 控件接受 alpha 组件小于 255 的 BackColor 以模拟透明
true); // 设置以上值为 true
base.UpdateStyles();
这段代码的意思就像注释里说的,注意ControlStyles这个枚举是可以按位组合的,所以上面要用「或(|)」来进行连接,这样系统就会完全忽视TabControl这个基类的界面显示,而使用我们自己的方式来呈现UI。
现在TabControlEx看起来是这样的。
啥米?!!OMG!东西哪去了??
嗯,当我第一次玩UserPaint的时候,也被吓了一跳。其实这就是上面我们设置的那句ControlStyles.UserPaint,于是系统就不帮我们画任何东西了。
所以从现在开始,一切都要靠自己了。下面所有的绘制都在OnPaint()方法中绘制。
为了先让我们找到方向,在OnPaint()方法中,我们先把Tab的位置找到,为此我们给每个Tab的边框都画出来。
[C#] 纯文本查看 复制代码
protected override void OnPaint(PaintEventArgs e)
{
for (int i = 0; i < this.TabCount; i++)
{
e.Graphics.DrawRectangle(Pens.Red, this.GetTabRect(i));
}
}
TabControl.GetTabRect(int)的功能是获得指定index的标签的矩形位置。画完后,我们的TabControlEx看起来不那么迷糊了。
可是,标签的大小还是不对,我们要的不是普通的那种长条,而是闷骚的苹果的瘦高型,要像这样。
嗯,好吧,我们回到构造函数,用下面的语句来设置大小。
[C#] 纯文本查看 复制代码
this.SizeMode = TabSizeMode.Fixed; // 大小模式为固定
this.ItemSize = new Size(44, 55); // 设定每个标签的尺寸
上面设置44x55其实只是因为苹果原版刚好是这么大,先这么着,后面如果不合适了,回头再来改。现在标签是这样的了。
Apple标签的选中状态是带阴影的,看起来很酷,可是如果我用GDI+来画的话,什么渐变什么变换,烦都烦死了。怎么办呢?
请记住,我们正在山寨。所谓山寨的精神,就是不问方法、不择手段,只要最后「看起来一样」就行了。所以,我决定用上抠图大法,把apple的背景图抠出来。
把这个背景保存为TabBackground.bmp文件,然后添加到项目中,把它做成「嵌入的资源」,就像这样。
然后我们用一个变量来保存背景图。因为这张图随时会用到,所以还是做成全局变量(类级别),在构造函数里读取图片。
[C#] 纯文本查看 复制代码
Image backImage;
public TabControlEx()
{
// (略)
backImage = new Bitmap(this.GetType(), "TabButtonBackground.bmp"); // 从资源文件(嵌入到程序集)里读取图片
}
现在有了图标,加上去看看吧。在OnPaint()里这样写。
[C#] 纯文本查看 复制代码
if (this.SelectedIndex == i)
{
e.Graphics.DrawImage(backImage, this.GetTabRect(i));
}
只有被选中的标签才会出现这种背景。于是,标签变成这样了。
绘制文字
这会看着还挺单调的,所以我们来加点料。下面来画文字。说起文字,我想你应该注意到了,Safari的标签文字,都是带有阴影的(准确的说是高光)。
所以,在绘制文字时,先用高光色绘制第一遍,再用普通文字色(黑)绘制第二遍。
[C#] 纯文本查看 复制代码
protected override void OnPaint(PaintEventArgs e)
{
for (int i = 0; i < this.TabCount; i++)
{
// (略)
// Calculate text position
Rectangle bounds = this.GetTabRect(i);
PointF textPoint = new PointF();
SizeF textSize = TextRenderer.MeasureText(this.TabPages.Text, this.Font);
// 注意要加上每个标签的左偏移量X
textPoint.X
= bounds.X + (bounds.Width - textSize.Width) / 2;
textPoint.Y
= bounds.Bottom - textSize.Height - this.Padding.Y;
// Draw highlights
e.Graphics.DrawString(
this.TabPages.Text,
this.Font,
SystemBrushes.ControlLightLight, // 高光颜色
textPoint.X,
textPoint.Y);
// 绘制正常文字
textPoint.Y--;
e.Graphics.DrawString(
this.TabPages.Text,
this.Font,
SystemBrushes.ControlText, // 正常颜色
textPoint.X,
textPoint.Y);
}
}
缤纷色彩的源泉:图标
文字也有了,那么接下来就轮到图标了。TabControl是用ImageList控件来存储自己使用的图标的,那么添加一个ImageList,然后加入图标。注意这里都要32x32的图标,所以应该设置ImageList.ImageSize为32x32。
[C#] 纯文本查看 复制代码
// 绘制图标
if (this.ImageList != null)
{
int index = this.TabPages.ImageIndex;
string key = this.TabPages.ImageKey;
Image icon = new Bitmap(1, 1);
if (index > -1)
{
icon = this.ImageList.Images[index];
}
if (!string.IsNullOrEmpty(key))
{
icon = this.ImageList.Images[key];
}
e.Graphics.DrawImage(
icon,
bounds.X + (bounds.Width - icon.Width) / 2,
bounds.Top + this.Padding.Y);
}
嗯,现在我们的标签看起来像那么回事了,接下来就该难看的红线条退休了。再完善一下,我们的标签就OK了。
同步滚动演示。(上面是山寨,下面是正品,正品的文字开了抗锯齿,山寨没开,这是次要问题)
到此,标签导航部分已经完成,剩下的,就是窗体的自动缩放和同步修改Text功能了。
案例源码下载:
仿苹果Safari浏览器选项卡自定义TabControl控件.rar
(100.3 KB, 下载次数: 1103, 售价: 1 金钱)
作者: evilatom 时间: 2015-1-27 09:06
好详细 不错
作者: CastleDrv 时间: 2015-1-27 12:52
支持技术贴
作者: 贱贱的贱贱 时间: 2015-1-28 02:15
CSDN野比...控件大神
作者: 乔克斯 时间: 2015-1-28 10:25
被发现了。
作者: psetpsetpset 时间: 2015-2-5 12:36
学习了。。。
作者: caurhy 时间: 2015-4-22 17:19
谢谢大神,学习了,正在编程学习中,感激~~~
作者: aruialy 时间: 2015-4-22 21:17
好东西,感谢楼主分享!
作者: 1048138294 时间: 2015-5-7 17:43
很不错的教程..
作者: chh919 时间: 2015-6-3 10:42
试试,感谢感谢。。。
作者: jacean 时间: 2015-6-12 12:30
楼主真棒,学习了!
作者: sniper808 时间: 2015-6-16 11:06
学习了,支持一下。
作者: 悲哀的小洋 时间: 2015-6-25 13:58
大神 顶一个
作者: ririkaka 时间: 2015-6-25 17:08
大神啊,学习了,感激~~~
作者: hp874a6 时间: 2015-9-15 13:15
效果挺好的控件,学习源码
作者: Jouz 时间: 2015-9-17 13:18
感谢楼主分享
作者: xulong20006 时间: 2015-9-23 19:02
偶像, 膜拜一个!
作者: heroesCS 时间: 2015-11-4 23:23
正在学习C#,开发插件,需要对控件进行美化,正好学习了
作者: 独来读网 时间: 2015-11-10 20:14
正好需要这个,发支持再下载
作者: su3817806 时间: 2015-12-16 12:02
很不错的教程..
作者: 小雨哗啦啦 时间: 2015-12-24 23:28
感谢分享
作者: 判囚 时间: 2016-2-20 11:54
感谢感谢。。。
作者: a583859818 时间: 2016-2-20 17:55
haodongxiahahahha
作者: jjzxc99 时间: 2016-2-21 01:31
666赞一个
作者: sinner 时间: 2016-3-17 10:35
不错啊.....
作者: lucien 时间: 2016-6-12 10:06
不错的教程~学习一下~
作者: Brennan 时间: 2016-6-12 15:27
Tab标签能居中显示不?
作者: 乔克斯 时间: 2016-6-12 16:19
不能。
作者: 279108435 时间: 2016-6-13 14:06
技术贴,支持
作者: gjk1100 时间: 2016-7-7 09:09
好详细 不错
作者: a620620 时间: 2016-7-28 22:28
好东西非常棒~!!
作者: Even 时间: 2016-7-29 08:08
猛.....下載來看看~
作者: hongjh2 时间: 2016-8-25 10:23
学习了,谢谢
作者: darker 时间: 2016-8-30 12:06
哈哈!控件大神!你好!!
作者: Arthas 时间: 2016-9-5 15:52
谢谢楼主分享
作者: QuXcc 时间: 2016-9-5 17:15
很漂亮的!不错
作者: QuXcc 时间: 2016-9-5 17:15
很漂亮的!不错
作者: darker 时间: 2016-9-14 00:22
收
作者: 言小言 时间: 2016-10-10 10:29
大神啊 太有用了
作者: 路过蜻蜓 时间: 2016-10-18 08:18
好详细 不错
作者: 路过蜻蜓 时间: 2016-10-18 08:18
好详细 不错
作者: sanliang 时间: 2016-10-19 10:17
我觉得只有乔帮主的最实惠了。
作者: ichinaec 时间: 2016-11-21 22:20
老板这写得很不错,不敢想像你真的是96年的么?功力这么深厚吗?
作者: ichinaec 时间: 2016-11-21 22:20
老板这写得很不错,不敢想像你真的是96年的么?功力这么深厚吗?
作者: ichinaec 时间: 2016-11-21 22:30
这个文章牛B得紧。
作者: wtf3505 时间: 2017-1-24 13:38
新手下载学习下
作者: fsnonlyone 时间: 2017-2-5 15:19
多谢楼主分享
作者: crio 时间: 2017-2-22 14:43
这个超级实用,比较适合新手
作者: jobfind 时间: 2017-3-2 17:07
感谢感谢。。。 感谢感谢。。。
作者: xxooonnmm 时间: 2017-7-30 22:44
很厉害学习啦
作者: kingkie 时间: 2017-8-2 15:11
这个老外写的不错
作者: youzis 时间: 2017-8-5 17:23
跪谢,,学习了。。。
作者: lcj21 时间: 2017-11-25 21:42
这个是真正的技术贴,必须支持一下,谢谢分享!
作者: spedit 时间: 2018-3-18 16:35
文章不错,支持一下。
作者: lichangjun_2018 时间: 2018-4-20 14:40
感谢分享,LZ辛苦了~
作者: 常长老 时间: 2018-4-22 18:57
好东西,必须学习之,哈哈
作者: wyksin 时间: 2019-1-9 11:25
感谢分享
作者: yueshang1 时间: 2019-2-28 21:10
CSDN野比...控件大神
作者: 鮮奶綠 时间: 2019-4-17 15:23
感谢分享,LZ辛苦了~
作者: 山水美 时间: 2019-4-18 09:12
控件大神!这是手把手在教,真心不错!支持技术帖!
作者: jy02046638 时间: 2019-9-18 22:01
感谢分享
作者: jxluo_koala 时间: 2020-3-25 22:38
学习了,感谢大神分享
作者: Kindergarten 时间: 2020-6-16 08:36
好详细 不错,GOOD
作者: blackcatabc 时间: 2020-9-25 17:14
好东西,感谢楼主分享!
作者: net10010 时间: 2021-3-5 14:42
感谢分享!
作者: 670725263 时间: 2024-5-6 10:19
感谢分享
作者: ldhtxy520 时间: 2024-5-7 09:59
好厉害,试试
作者: ldhtxy520 时间: 2024-5-7 09:59
好厉害,试试
欢迎光临 CSkin博客 (http://bbs.cskin.net/) |
Powered by Discuz! X3.2 |