1。新建一个项目
2。添加一个用户控件“PaneCaption.vb”
3。[操作]调整控件大小为150×30
4。打开代码编辑器:
Imports System.Drawing.Drawing2D
Imports System.ComponentModel
Public Class PaneCaption
' 常量设置
Private Class Consts
Public Const DefaultHeight As Integer = 20
Public Const DefaultFontName As String = "arial"
Public Const DefaultFontSize As Integer = 9
Public Const PosOffset As Integer = 4
End Class
' 内部成员
Private _active As Boolean = False
Private _antiAlias As Boolean = True
Private _allowActive As Boolean = True
Private _colorActiveText As Color = Color.Black
Private _colorInactiveText As Color = Color.White
Private _colorActiveLow As Color = Color.FromArgb(255, 165, 78)
Private _colorActiveHigh As Color = Color.FromArgb(255, 225, 155)
Private _colorInactiveLow As Color = Color.FromArgb(3, 55, 145)
Private _colorInactiveHigh As Color = Color.FromArgb(90, 135, 215)
' 绘图对象
Private _brushActiveText As SolidBrush
Private _brushInactiveText As SolidBrush
Private _brushActive As LinearGradientBrush
Private _brushInactive As LinearGradientBrush
Private _format As StringFormat
' 公共参数
' 控件标题
<Category("Appearance"), Browsable(True), _
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), _
Description("Text that is displayed in the label.")> _
Public Shadows Property Text() As String
Get
Return MyBase.Text
End Get
Set(ByVal Value As String)
MyBase.Text = Value
Invalidate()
End Set
End Property
' 标题栏是否激活
<Description("The active state of the caption, draws the caption with different gradient colors."), _
Category("Appearance"), DefaultValue(False)> _
Public Property Active() As Boolean
Get
Return _active
End Get
Set(ByVal value As Boolean)
_active = value
Invalidate()
End Set
End Property
' 是否应该包含活动和非活动状态
<Description("True always uses the inactive state colors, false maintains an active and inactive state."), _
Category("Appearance"), DefaultValue(True)> _
Public Property AllowActive() As Boolean
Get
Return _allowActive
End Get
Set(ByVal value As Boolean)
_allowActive = value
Invalidate()
End Set
End Property
' 防锯齿模式
<Description("If should draw the text as antialiased."), _
Category("Appearance"), DefaultValue(True)> _
Public Property AntiAlias() As Boolean
Get
Return _antiAlias
End Get
Set(ByVal value As Boolean)
_antiAlias = value
Invalidate()
End Set
End Property
颜色属性
' 内部属性
' 绘制标题的画刷
Private ReadOnly Property TextBrush() As SolidBrush
Get
Return DirectCast(IIf(_active AndAlso _allowActive, _
_brushActiveText, _brushInactiveText), SolidBrush)
End Get
End Property
' 背景渐变色
Private ReadOnly Property BackBrush() As LinearGradientBrush
Get
Return DirectCast(IIf(_active AndAlso _allowActive, _
_brushActive, _brushInactive), LinearGradientBrush)
End Get
End Property
' 构造函数
Public Sub New()
MyBase.New()
' 窗体设计器调用
InitializeComponent()
' 设置双缓冲样式
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
ControlStyles.AllPaintingInWmPaint Or ControlStyles.ResizeRedraw, True)
' 初始化高度
Me.Height = Consts.DefaultHeight
' 文本的格式
_format = New StringFormat
_format.FormatFlags = StringFormatFlags.NoWrap
_format.LineAlignment = StringAlignment.Center
_format.Trimming = StringTrimming.EllipsisCharacter
' 初始化字体
Me.Font = New Font(Consts.DefaultFontName, Consts.DefaultFontSize, FontStyle.Bold)
' 创建GDI对象
Me.ActiveTextColor = _colorActiveText
Me.InactiveTextColor = _colorInactiveText
' 创建渐变颜色效果画刷
CreateGradientBrushes()
End Sub
' 内部成员
' 需要重绘标题
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
DrawCaption(e.Graphics)
MyBase.OnPaint(e)
End Sub
' 绘制标题
Private Sub DrawCaption(ByVal g As Graphics)
' 背景
g.FillRectangle(Me.BackBrush, Me.DisplayRectangle)
' 标题
If _antiAlias Then
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
End If
' 使用省略号时需要一个矩形
Dim bounds As RectangleF = New RectangleF(Consts.PosOffset, 0, _
Me.DisplayRectangle.Width - Consts.PosOffset, Me.DisplayRectangle.Height)
g.DrawString(Me.Text, Me.Font, Me.TextBrush, bounds, _format)
End Sub
' 重写该函数,处理单击标题产生的事件
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
MyBase.OnMouseDown(e)
If Me._allowActive Then Me.Focus()
End Sub
Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
MyBase.OnSizeChanged(e)
' 重绘
CreateGradientBrushes()
End Sub
Private Sub CreateGradientBrushes()
' 允许重绘的高度和宽度条件
If Me.Width > 0 AndAlso Me.Height > 0 Then
If Not (_brushActive Is Nothing) Then _brushActive.Dispose()
_brushActive = New LinearGradientBrush(Me.DisplayRectangle, _
_colorActiveHigh, _colorActiveLow, LinearGradientMode.Vertical)
If Not (_brushInactive Is Nothing) Then _brushInactive.Dispose()
_brushInactive = New LinearGradientBrush(Me.DisplayRectangle, _
_colorInactiveHigh, _colorInactiveLow, LinearGradientMode.Vertical)
End If
End Sub
End Class
5。按F5编译并保存
6。 建立一个基类 “BasePane.vb”
该基类将使用到前面定义的面板标题类,也属于用户控件。提供对绘图、改变大小、焦点控制等事件进行处理的基本功能。
7。[操作]双击之前生成的用户控件PaneCaption加入到工作区,该操作将定义一个PaneCaption1的实例,改名为"caption"。注意:新的组建要在重新编译后才能在工具栏中出现。
8。打开代码编辑器:
’ Base class for the three panes. Draws caption at top with using
’ a different gradient fill if the pane is active or inactive.
Imports System.ComponentModel
Public Class BasePane
Inherits System.Windows.Forms.UserControl
' events
' raise when the pane becomes active
Public Event PaneActive(ByVal sender As Object, ByVal e As EventArgs)
' internal members
' pane caption
Private caption As PaneCaption
' properties
Protected ReadOnly Property CaptionControl() As PaneCaption
Get
Return caption
End Get
End Property
<Description("The pane caption."), Category("Appearance")> _
Public Property CaptionText() As String
Get
Return caption.Text
End Get
Set(ByVal value As String)
caption.Text = value
End Set
End Property
Public ReadOnly Property Active() As Boolean
Get
Return caption.Active
End Get
End Property
' ctor
Public Sub New()
MyBase.New()
' set double buffer styles
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
ControlStyles.AllPaintingInWmPaint Or ControlStyles.ResizeRedraw, True)
' This call is required by the Windows.Forms Form Designer.
InitializeComponent()
End Sub
Windows Form Designer generated code
' internal methods
' received focus, make this the active pane
Protected Overrides Sub OnEnter(ByVal e As System.EventArgs)
MyBase.OnEnter(e)
caption.Active = True
RaiseEvent PaneActive(Me, EventArgs.Empty)
End Sub
' lost focus, not the active pane
Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)
MyBase.OnLeave(e)
caption.Active = False
End Sub
' draw border around the pane
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim rc As New Rectangle(0, 0, Me.Width - 1, Me.Height - 1)
rc.Inflate(-Me.DockPadding.All + 1, -Me.DockPadding.All + 1)
e.Graphics.DrawRectangle(SystemPens.ControlDark, rc)
MyBase.OnPaint(e)
End Sub
Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
MyBase.OnResize(e)
' manually resize the caption width if in the visual designer
If Me.DesignMode Then
caption.Width = Me.Width
End If
End Sub
End Class
9。按F5编译保存
10。新建一个用户控件"testPane.vb"
11。加入代码:
Public Class testPane
Inherits FotoVision.BasePane
End Class
12。将testPane控件拖到Form1.vb里面编译,就可以看到具有渐变色风格的标题的面板啦,多拖几个可以切换焦点。