zoukankan      html  css  js  c++  java
  • IssueVision的PaneCaption控件源码分析

     今天看了看IssueVision的源代码,把学习中的东西记录下来,以免忘掉了。

    ' Custom control that draws the caption for each pane. Contains an active 
    '
     state and draws the caption different for each state. Caption is drawn
    '
     with a gradient fill and antialias font.


    Imports System.Drawing.Drawing2D '使用GDI+绘制渐变背景和表面文字需要引用的类
    Imports System.ComponentModel

    Public Class PaneCaption
        
    Inherits System.Windows.Forms.UserControl

        
    ' const values
        '用来控制控件表面文字绘制的属性和控件默认的缺省属性
        Private Class Consts
            
    Public Const DefaultHeight As Integer = 26
            
    Public Const DefaultFontName As String = "Tahoma"
            Public Const DefaultFontSize As Integer = 12
            
    Public Const PosOffset As Integer = 4 '文字相对于容器的绘制坐标位移
        End Class


        
    ' internal members
        Private m_active As Boolean = False '控件激活和无效两种状态控制
        Private m_antiAlias As Boolean = True '用来控制控件表面文字的显示质量
        Private m_allowActive As Boolean = True
        
    Private m_text As String = ""

        '两种状态默认文字、背景渐变颜色
        Private m_colorActiveText As Color = Color.Black
        
    Private m_colorInactiveText As Color = Color.White

        
    Private m_colorActiveLow As Color = Color.FromArgb(25516578)
        
    Private m_colorActiveHigh As Color = Color.FromArgb(255225155)
        
    Private m_colorInactiveLow As Color = Color.FromArgb(355145)
        
    Private m_colorInactiveHigh As Color = Color.FromArgb(90135215)

        
    ' gdi objects
        '绘制显示效果的笔刷
        Private m_brushActiveText As SolidBrush
        
    Private m_brushInactiveText As SolidBrush
        
    Private m_brushActive As LinearGradientBrush
        
    Private m_brushInactive As LinearGradientBrush
        
    Private m_format As StringFormat


        
    ' public properties

        
    ' the caption of the control
        '设置控件中的文本,并且在属性面板中可以选择
        <Description("Text displayed in the caption."), _
        Category(
    "Appearance"), DefaultValue("")> _
        
    Public Property Caption() As String
            
    Get
                
    Return m_text
            
    End Get

            
    Set(ByVal value As String)
                m_text 
    = value
                Invalidate() 
    '重会控件的显示
            End Set
        
    End Property


        
    '两个同样的属性,但是在即使按照上边控制Caption属性的方式来控制Text属性,属性面板中也不显示Text属性,不知动为什么?
        Public Overrides Property Text() As String
            
    Get
                
    Return Me.Caption
            
    End Get
            
    Set(ByVal Value As String)
                Me.Caption 
    = Value
            
    End Set
        
    End Property


        
    ' if the caption is active or not
        <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 m_active
            
    End Get
            
    Set(ByVal value As Boolean)
                m_active 
    = value
                Invalidate()
            
    End Set
        
    End Property


        
    ' if should maintain an active and inactive state
        <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 m_allowActive
            
    End Get
            
    Set(ByVal value As Boolean)
                m_allowActive 
    = value
                Invalidate()
            
    End Set
        
    End Property


        
    ' if the caption is active or not
        <Description("If should draw the text as antialiased."), _
         Category(
    "Appearance"), DefaultValue(True)> _
        
    Public Property AntiAlias() As Boolean
            
    Get
                
    Return m_antiAlias
            
    End Get
            
    Set(ByVal value As Boolean)
                m_antiAlias 
    = value
                Invalidate()
            
    End Set
        
    End Property


    #Region 
    " color properties "

        <Description("Color of the text when active."), _
        Category(
    "Appearance"), DefaultValue(GetType(Color), "Black")> 
    _
        
    Public Property ActiveTextColor() As Color
            
    Get
                
    Return m_colorActiveText
            
    End Get
            
    Set(ByVal Value As Color)
                
    If Value.Equals(Color.Empty) Then Value = Color.Black
                m_colorActiveText 
    = Value
                m_brushActiveText 
    = New SolidBrush(m_colorActiveText)
                Invalidate()
            
    End Set
        
    End Property


        
    <Description("Color of the text when inactive."), _
        Category(
    "Appearance"), DefaultValue(GetType(Color), "White")> _
        
    Public Property InactiveTextColor() As Color
            
    Get
                
    Return m_colorInactiveText
            
    End Get
            
    Set(ByVal Value As Color)
                
    If Value.Equals(Color.Empty) Then Value = Color.White
                m_colorInactiveText 
    = Value
                m_brushInactiveText 
    = New SolidBrush(m_colorInactiveText)
                Invalidate()
            
    End Set
        
    End Property


        
    <Description("Low color of the active gradient."), _
        Category(
    "Appearance"), DefaultValue(GetType(Color), "255, 165, 78")> _
        
    Public Property ActiveGradientLowColor() As Color
            
    Get
                
    Return m_colorActiveLow
            
    End Get
            
    Set(ByVal Value As Color)
                
    If Value.Equals(Color.Empty) Then Value = Color.FromArgb(25516578)
                m_colorActiveLow 
    = Value
                CreateGradientBrushes()
                Invalidate()
            
    End Set
        
    End Property


        
    <Description("High color of the active gradient."), _
        Category(
    "Appearance"), DefaultValue(GetType(Color), "255, 225, 155")> _
        
    Public Property ActiveGradientHighColor() As Color
            
    Get
                
    Return m_colorActiveHigh
            
    End Get
            
    Set(ByVal Value As Color)
                
    If Value.Equals(Color.Empty) Then Value = Color.FromArgb(255225155)
                m_colorActiveHigh 
    = Value
                CreateGradientBrushes()
                Invalidate()
            
    End Set
        
    End Property


        
    <Description("Low color of the inactive gradient."), _
          Category(
    "Appearance"), DefaultValue(GetType(Color), "3, 55, 145")> _
          
    Public Property InactiveGradientLowColor() As Color
            
    Get
                
    Return m_colorInactiveLow
            
    End Get
            
    Set(ByVal Value As Color)
                
    If Value.Equals(Color.Empty) Then Value = Color.FromArgb(355145)
                m_colorInactiveLow 
    = Value
                CreateGradientBrushes()
                Invalidate()
            
    End Set
        
    End Property


        
    <Description("High color of the inactive gradient."), _
          Category(
    "Appearance"), DefaultValue(GetType(Color), "90, 135, 215")> _
          
    Public Property InactiveGradientHighColor() As Color
            
    Get
                
    Return m_colorInactiveHigh
            
    End Get
            
    Set(ByVal Value As Color)
                
    If Value.Equals(Color.Empty) Then Value = Color.FromArgb(90135215)
                m_colorInactiveHigh 
    = Value
                CreateGradientBrushes()
                Invalidate()
            
    End Set
        
    End Property


    #
    End Region

        
    ' internal properties

        
    ' brush used to draw the caption
        Private ReadOnly Property TextBrush() As SolidBrush
            
    Get
                
    Return CType(IIf(m_active AndAlso m_allowActive, _
                 m_brushActiveText, m_brushInactiveText), SolidBrush)
            
    End Get
        
    End Property


        
    ' gradient brush for the background
        Private ReadOnly Property BackBrush() As LinearGradientBrush
            
    Get
                
    Return CType(IIf(m_active AndAlso m_allowActive, _
                 m_brushActive, m_brushInactive), LinearGradientBrush)
            
    End Get
        
    End Property


        
    ' ctor
        Public Sub New()
            
    MyBase.New()

            
    ' this call is required by the Windows Form Designer
            InitializeComponent()

            
    ' set double buffer styles
            '设置双重缓冲,以改善控件的显示效果
            Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint Or _
             ControlStyles.AllPaintingInWmPaint 
    Or ControlStyles.ResizeRedraw, True)

            
    ' init the height
            Me.Height = Consts.DefaultHeight

            
    ' format used when drawing the text
            m_format = New StringFormat
            m_format.FormatFlags 
    = StringFormatFlags.NoWrap
            m_format.LineAlignment = StringAlignment.Center '保证控件中文字的垂直对齐效果

            '在不完全适合布局形状的字符串中修整字符,指定将文本修整成最接近的字符,并在被修整的行的末尾插入一个省略号
            m_format.Trimming = StringTrimming.EllipsisCharacter

            
    ' init the font
            Me.Font = New Font(Consts.DefaultFontName, Consts.DefaultFontSize, FontStyle.Bold)

            
    ' create gdi objects
            Me.ActiveTextColor = m_colorActiveText
            Me.InactiveTextColor 
    = m_colorInactiveText

            
    ' setting the height above actually does this, but leave
            ' in incase change the code (and forget to init the 
            ' gradient brushes)
            CreateGradientBrushes()
        
    End Sub


        
    ' internal methods

        
    ' the caption needs to be drawn
        Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)

            
    MyBase.OnPaint(e)
            DrawCaption(e.Graphics)
        
    End Sub


        
    ' draw the caption
        Private Sub DrawCaption(ByVal g As Graphics)
            
    ' background
            g.FillRectangle(Me.BackBrush, Me.DisplayRectangle)

            
    ' caption
            If m_antiAlias Then
                
    '控制文本呈现模式,指定在无提示的情况下使用每个字符的 AntiAlias
                '标志符号位图来绘制字符。由于采用了 AntiAlias,质量会得到改善。
                '由于关闭了提示,主干宽度差可能会比较明显。
                g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
            End If

            
    ' need a rectangle when want to use ellipsis
            '绘制区域相对于控件有一定的位移
            Dim bounds As RectangleF = New RectangleF(Consts.PosOffset, 0, _
             Me.DisplayRectangle.Width 
    - Consts.PosOffset, Me.DisplayRectangle.Height)

            g.DrawString(m_text, Me.Font, Me.TextBrush, bounds, m_format)
        
    End Sub


        
    ' clicking on the caption does not give focus,
        ' handle the mouse down event and set focus to self
        Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
            
    MyBase.OnMouseDown(e)
            
    If Me.m_allowActive Then Me.Focus()
        
    End Sub


        
    Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
            
    MyBase.OnSizeChanged(e)

            
    ' create the gradient brushes based on the new size
            CreateGradientBrushes()
        
    End Sub


        
    Private Sub CreateGradientBrushes()
            
    ' can only create brushes when have a width and height
            If Me.Width > 0 AndAlso Me.Height > 0 Then
                
    If Not (m_brushActive Is NothingThen m_brushActive.Dispose()
                m_brushActive 
    = New LinearGradientBrush(Me.DisplayRectangle, _
                 m_colorActiveHigh, m_colorActiveLow, LinearGradientMode.Vertical)

                
    If Not (m_brushInactive Is NothingThen m_brushInactive.Dispose()
                m_brushInactive 
    = New LinearGradientBrush(Me.DisplayRectangle, _
                  m_colorInactiveHigh, m_colorInactiveLow, LinearGradientMode.Vertical)
            
    End If
        
    End Sub



    #Region 
    " Windows Form Designer generated code "

        'UserControl overrides dispose to clean up the component list.
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            
    If disposing Then
                
    If Not (components Is NothingThen
                    components.Dispose()
                
    End If
            
    End If
            
    MyBase.Dispose(disposing)
        
    End Sub


        
    'Required by the Windows Form Designer
        Private components As System.ComponentModel.IContainer

        
    'NOTE: The following procedure is required by the Windows Form Designer
        'It can be modified using the Windows Form Designer.  
        'Do not modify it using the code editor.
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            
    '
            'PaneCaption
            '
            Me.Name = "PaneCaption"
            Me.Size = New System.Drawing.Size(15030)
        
    End Sub


    #
    End Region

    End Class


    这是个很简单的控件,但是我想对初学者应该是有帮助的,主要体现在以下几点:

    背景的渐变绘制

    表面文字质量的控制

    设计过程中的控件绘制控制

    文字与控件调整的关系

    属性面板的控制

    总结一下:
    由于是第一次学习制作控件,看看这个源代码对自己的帮助是很大的,在.Net中制作控件相对于VB可能略微复杂一点,但是效果要好很多,在我们现有的项目中原先的Panel控件完全是结合图片+Label来制作的,灵活性和资源利用率要差很多,采用GDI+来绘制控件,效果和质量要好很多。看这段代码应该对组件的制作和GDI+能有更好的理解和认识。

    在自己仿照的编写过程中,基本上是看代码和帮助来完成的,发生了两个很笨的事情,一个是设计完组件,没有编译便想使用,结果控件无法使用,所有如果在项目中控件修改了,至少要编译一次在使用。另一个是设计完的控件找不到,后来在工具箱中找到我得用户控件才找到,笨呀.




  • 相关阅读:
    pydev 下Django 1.7 undefined variables from import问题的解决
    前端CDN公共库整理
    BugFix:URL or HTTP headers are too long (IP=127.0.0.1)
    目前最好用的软件下载网站
    mysql数据库优化之表的设计和慢查询定位
    Hadoop-08-Hive本地独立式安装
    AspNetPager真假分页对照实例
    Android从无知到有知——NO.6
    Xpath—解决这个问题的良药
    C# Json反序列化 数据协定类型 无法反序列化 由于未找到必需的数据成员
  • 原文地址:https://www.cnblogs.com/Duiker/p/101402.html
Copyright © 2011-2022 走看看