在 .NET 2.0 中为 TabControl 应用视觉样式






2.73/5 (5投票s)
2006 年 4 月 11 日
1分钟阅读

73384

722
为 TabControl 应用 XP 风格,并带有快捷键功能。
引言
我曾经在使用 Visual Studio 2005 中包含的 TabControl
时遇到一个大问题。所以我为 TabControl
应用了一个“助记符”(快捷键)功能,因此我将 DrawMode
属性设置为 OwnerDrawFixed
。但是,设置此属性会移除按钮的 XP 风格。
所以我尝试实现 DrawItem
事件来重新绘制按钮,但似乎没有效果。我甚至尝试了网上免费提供的“Sky Bound 组件”,但它不符合我的要求。
所以,最终我决定构建自己的控件。我在互联网上搜索了一些相关资源,但对找到的内容并不满意。
所以,这里是这个控件,我已经在其中应用了 XP 风格和快捷键功能。
背景
首先,我们需要设置双缓冲技术来改善绘制效果,并允许控件改变其外观
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
然后,您需要重写 OnPaint
事件并绘制自己的控件。涉及的基本步骤是
Protected Overrides Function ProcessMnemonic(ByVal charCode As Char) As Boolean
For Each p As TabPage In Me.TabPages
If Control.IsMnemonic(charCode, p.Text) Then
Me.SelectedTab = p
Me.Focus()
Return True
End If
Next p
Return False
End Function 'ProcessMnemonic
Protected Overrides Sub OnPaint(ByVal e As _
System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
DrawControl(e.Graphics)
End Sub
Friend Sub DrawControl(ByVal g As Graphics)
If Not Visible Then
Return
End If
Dim render As New VisualStyleRenderer(VisualStyleElement.Tab.Pane.Normal)
Dim TabControlArea As Rectangle = Me.ClientRectangle
Dim TabArea As Rectangle = Me.DisplayRectangle
TabArea.Y = TabArea.Y + 1
TabArea.Width = TabArea.Width + 1
Dim nDelta As Integer = SystemInformation.Border3DSize.Width
TabArea.Inflate(nDelta, nDelta)
render.DrawBackground(g, TabArea)
Dim i As Integer = 0
While i < Me.TabCount
DrawTab(g, Me.TabPages(i), i)
i += 1
End While
End Sub
Friend Sub DrawTab(ByVal g As Graphics, ByVal tabPage _
As TabPage, ByVal nIndex As Integer)
Dim recBounds As Rectangle = Me.GetTabRect(nIndex)
Dim tabTextArea As RectangleF = _
CType(Me.GetTabRect(nIndex), RectangleF)
Dim bSelected As Boolean = (Me.SelectedIndex = nIndex)
Dim render As New VisualStyleRenderer(VisualStyleElement.Tab.Pane.Normal)
render = New VisualStyleRenderer(VisualStyleElement.Tab.TabItem.Pressed)
If bSelected Then
recBounds.Height = recBounds.Height + 10
render = New VisualStyleRenderer(VisualStyleElement.Tab.TabItem.Pressed)
render.DrawBackground(g, recBounds)
render.DrawEdge(g, recBounds, Edges.Diagonal, _
EdgeStyle.Sunken, EdgeEffects.Flat)
Else
recBounds.Y = recBounds.Y + 1
render = New VisualStyleRenderer(VisualStyleElement.Tab.TabItem.Normal)
render.DrawBackground(g, recBounds)
render.DrawEdge(g, recBounds, Edges.Diagonal, _
EdgeStyle.Sunken, EdgeEffects.Flat)
End If
If (tabPage.ImageIndex >= 0) AndAlso _
(Not (ImageList Is Nothing)) _
AndAlso (Not (ImageList.Images(tabPage.ImageIndex) _
Is Nothing)) Then
Dim nLeftMargin As Integer = 8
Dim nRightMargin As Integer = 2
Dim img As Image = ImageList.Images(tabPage.ImageIndex)
Dim rimage As Rectangle = New Rectangle(recBounds.X + _
nLeftMargin, recBounds.Y + 1, img.Width, img.Height)
Dim nAdj As Single = CType((nLeftMargin + _
img.Width + nRightMargin), Single)
rimage.Y += (recBounds.Height - img.Height) / 2
tabTextArea.X += nAdj
tabTextArea.Width -= nAdj
g.DrawImage(img, rimage)
End If
Dim stringFormat As StringFormat = New StringFormat
stringFormat.Alignment = StringAlignment.Center
stringFormat.LineAlignment = StringAlignment.Center
If FlagControl Then
stringFormat.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Show
Else
stringFormat.HotkeyPrefix = Drawing.Text.HotkeyPrefix.Hide
End If
Dim br As Brush
br = New SolidBrush(tabPage.ForeColor)
g.DrawString(tabPage.Text, Font, br, tabTextArea, stringFormat)
End Sub
Using the Code
要使用此代码,只需将引用添加到 TabControl
到新项目中,并将 TabControl
拖到您的窗体上即可。
注意
请留下您的评论、更正或补充,以表示感谢。您的反馈将不胜感激。