【美化TabControl教程】仿苹果Safari浏览器选项卡
一步一步玩控件:自定义TabControl——从山寨Apple Safari开始
教程:
分析,分析
山寨的灵魂在于分析,首先把刚才拍的高清果照扯过来分解了。
1337277056_9776.jpg (65.87 KB, 下载次数: 30)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:03 上传
我把他分解成这几个部分:
- 根据标签不同修改窗体标题
- 导航标签
- 标签面板
- 自动缩放
- 这篇是#1-1,就专心讨论关于标签的东西,也就是第2、3点。
- 组件设计
- 分析了其中的功能,那么就要想想怎么来实现。
- 从功能来看,这个窗口实际上是由多个子面板切换来实现的,最多他加了点自动缩放。所以从本质来说,还是一个标签切换的窗口。
- 我最早想到的就是大名鼎鼎却又丑得无以复加的TabControl。
1337277420_4232.jpg (4.33 KB, 下载次数: 3)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:03 上传
按照标签切换这个思想,TabControl完全可以胜任这次的山寨需求。但是TabControl这么丑,必须要给它整整容才行。想不到我竟然有整容的才华。
下手吧,年轻人!
因为要改动的地方会很多,所以还是完全自己来绘制标签好了。为了完全自定义TabControl,同时方便循环利用,从TabControl派生一个我们自己的标签控件TabControlEx。
[C#]
纯文本查看
复制代码
?
| 1 | publicclassTabControlEx : System.Windows.Forms.TabControl |
1337280435_7643.jpg (6.43 KB, 下载次数: 13)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:05 上传
这就是我们的TabControlEx,看起来和TabControl没什么两样(那是当然的)。
为了让他看起来不太一样,在构造函数里加上下面的代码。
[C#]
纯文本查看
复制代码
?
| 1 2 3 4 5 6 7 8 | 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看起来是这样的。
1337280718_2725.jpg (2.08 KB, 下载次数: 22)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:06 上传
啥米?!!OMG!东西哪去了??
嗯,当我第一次玩UserPaint的时候,也被吓了一跳。其实这就是上面我们设置的那句ControlStyles.UserPaint,于是系统就不帮我们画任何东西了。
所以从现在开始,一切都要靠自己了。下面所有的绘制都在OnPaint()方法中绘制。
为了先让我们找到方向,在OnPaint()方法中,我们先把Tab的位置找到,为此我们给每个Tab的边框都画出来。
[C#]
纯文本查看
复制代码
?
| 1 2 3 4 5 6 7 | protectedoverridevoidOnPaint(PaintEventArgs e) { for(inti = 0; i <this.TabCount; i ) { e.Graphics.DrawRectangle(Pens.Red,this.GetTabRect(i)); } } |
TabControl.GetTabRect(int)的功能是获得指定index的标签的矩形位置。画完后,我们的TabControlEx看起来不那么迷糊了。
1337281216_7993.jpg (5.29 KB, 下载次数: 3)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
可是,标签的大小还是不对,我们要的不是普通的那种长条,而是闷骚的苹果的瘦高型,要像这样。
1337281308_8997.jpg (1.57 KB, 下载次数: 4)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
嗯,好吧,我们回到构造函数,用下面的语句来设置大小。
[C#]
纯文本查看
复制代码
?
| 1 2 | this.SizeMode = TabSizeMode.Fixed; // 大小模式为固定 this.ItemSize =newSize(44, 55); // 设定每个标签的尺寸 |
上面设置44×55其实只是因为苹果原版刚好是这么大,先这么着,后面如果不合适了,回头再来改。现在标签是这样的了。
1337281579_7315.jpg (5.17 KB, 下载次数: 3)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
Apple标签的选中状态是带阴影的,看起来很酷,可是如果我用GDI 来画的话,什么渐变什么变换,烦都烦死了。怎么办呢?
请记住,我们正在山寨。所谓山寨的精神,就是不问方法、不择手段,只要最后「看起来一样」就行了。所以,我决定用上抠图大法,把apple的背景图抠出来。
1337282332_7191.jpg (18.68 KB, 下载次数: 7)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
把这个背景保存为TabBackground.bmp文件,然后添加到项目中,把它做成「嵌入的资源」,就像这样。
1337282889_1098.jpg (69.82 KB, 下载次数: 5)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
然后我们用一个变量来保存背景图。因为这张图随时会用到,所以还是做成全局变量(类级别),在构造函数里读取图片。
[C#]
纯文本查看
复制代码
?
| 1 2 3 4 5 6 | Image backImage; publicTabControlEx() { // (略) backImage =newBitmap(this.GetType(),”TabButtonBackground.bmp”); // 从资源文件(嵌入到程序集)里读取图片 } |
现在有了图标,加上去看看吧。在OnPaint()里这样写。
[C#]
纯文本查看
复制代码
?
| 1 2 3 4 | if(this.SelectedIndex == i) { e.Graphics.DrawImage(backImage,this.GetTabRect(i)); } |
只有被选中的标签才会出现这种背景。于是,标签变成这样了。
1337283371_8418.jpg (4.88 KB, 下载次数: 5)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
绘制文字
这会看着还挺单调的,所以我们来加点料。下面来画文字。说起文字,我想你应该注意到了,Safari的标签文字,都是带有阴影的(准确的说是高光)。
1337284238_1566.jpg (30.42 KB, 下载次数: 8)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
所以,在绘制文字时,先用高光色绘制第一遍,再用普通文字色(黑)绘制第二遍。
[C#]
纯文本查看
复制代码
?
| 01 02 03 04 05 06 07 08 09 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 | protectedoverridevoidOnPaint(PaintEventArgs e) { for(inti = 0; i <this.TabCount; i ) { // (略) // Calculate text position Rectangle bounds =this.GetTabRect(i); PointF textPoint =newPointF(); 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); } } |
1337285494_5143.jpg (5.72 KB, 下载次数: 1)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
缤纷色彩的源泉:图标
文字也有了,那么接下来就轮到图标了。TabControl是用ImageList控件来存储自己使用的图标的,那么添加一个ImageList,然后加入图标。注意这里都要32×32的图标,所以应该设置ImageList.ImageSize为32×32。
[C#]
纯文本查看
复制代码
?
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | // 绘制图标 if(this.ImageList !=null) { intindex =this.TabPages.ImageIndex; stringkey =this.TabPages.ImageKey; Image icon =newBitmap(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); } |
1337286432_6741.jpg (6.38 KB, 下载次数: 1)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
嗯,现在我们的标签看起来像那么回事了,接下来就该难看的红线条退休了。再完善一下,我们的标签就OK了。
1337286562_3591.jpg (19.39 KB, 下载次数: 2)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
1337286616_1939.jpg (22.66 KB, 下载次数: 3)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
同步滚动演示。(上面是山寨,下面是正品,正品的文字开了抗锯齿,山寨没开,这是次要问题)
1337286976_6987.gif (98.8 KB, 下载次数: 4)
【美化TabControl教程】仿苹果Safari浏览器选项卡
2015-1-26 18:08 上传
到此,标签导航部分已经完成,剩下的,就是窗体的自动缩放和同步修改Text功能了
资源文件列表
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/bin/Debug/tabform.exe , 39424
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/frm_Main.cs , 551
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/frm_Main.Designer.cs , 18184
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/frm_Main.resx , 26145
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/DesignTimeResolveAssemblyReferences.cache , 6149
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache , 6167
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/Nobi's TabbedForm.csproj.FileListAbsolute.txt , 503
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/SprinbearWorks.WinForms.Form1.resources , 13800
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/SprinbearWorks.WinForms.frm_Main.resources , 13800
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/SprinbearWorks.WinForms.Properties.Resources.resources , 180
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/Tab.csproj.FileListAbsolute.txt , 981
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/Tab.csproj.GenerateResource.Cache , 850
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/Tab.csprojResolveAssemblyReference.cache , 1341
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/tabform.exe , 39424
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/tabform.pdb , 28160
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll , 4608
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Program.cs , 485
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Properties/AssemblyInfo.cs , 1206
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Properties/Resources.Designer.cs , 2886
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Properties/Resources.resx , 5612
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Properties/Settings.Designer.cs , 1123
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Properties/Settings.settings , 249
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Tab.csproj , 5144
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Tab.csproj.user , 452
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Tab.sln , 895
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Tab.suo , 19968
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/Tab.v12.suo , 38912
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/TabButtonBackground.bmp , 7314
仿苹果Safari浏览器选项卡自定义TabControl控件/Tab/TabControlEx.cs , 6186
