Home >> ヒント・サンプル集 >> プログラムサンプル >> (VB.net特殊なボタン(VB2015)

<VB.net> 特殊なボタン(VB2015)

お客様から、一部のボタンを通常のボタンではなく、このようなボタンにしてほしいとの要望がありました

画像をボタンに貼り付けても良いのですが、ユーザーコントロールに挑戦してみました


Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

Public Class spColorButton
    Inherits System.Windows.Forms.Button
    Private _pushed As Boolean
    Private _Option As Int16 ' gradation Option 0:linear 1:Path
    Private _mode As Drawing2D.LinearGradientMode
    Private _Color1 As Color ' Gradient Start Color
    Private _Color2 As Color ' Gradient End Color
    Private _borderWidth As Int16 ' border line widht
    Private _borderColor As Color ' border line color
    Private _PointX As Int16 ' 
    Private _PointY As Int16 ' 
    Private _Checked As ButtonState

    Private _bmpOffScreen As Bitmap
    Private _imageAttr As System.Drawing.Imaging.ImageAttributes

    Public Property Mode() As Drawing2D.LinearGradientMode
        Get
            Return _mode
        End Get
        Set(ByVal value As Drawing2D.LinearGradientMode)
            _mode = value
        End Set
    End Property

    Public Property BorderWidth() As Int16
        Get
            Return _borderWidth
        End Get
        Set(ByVal value As Int16)
            _borderWidth = value
        End Set
    End Property

    Public Property BorderColor() As Color
        Get
            Return _borderColor
        End Get
        Set(ByVal value As Color)
            _borderColor = value
        End Set
    End Property

    Public Property Color1() As Color
        Get
            Return _Color1
        End Get
        Set(ByVal value As Color)
            _Color1 = value
        End Set
    End Property

    Public Property Color2() As Color
        Get
            Return _Color2
        End Get
        Set(ByVal value As Color)
            _Color2 = value
        End Set
    End Property

    Public Property Goption() As Int16
        Get
            Return _Option
        End Get
        Set(ByVal value As Int16)
            _Option = value
        End Set
    End Property

    Public Property CenterPoint() As Drawing.Point
        Get
            Return New Drawing.Point(_PointX, _PointY)
        End Get
        Set(ByVal value As Drawing.Point)
            _PointX = value.X
            _PointY = value.Y
        End Set
    End Property

    Public Property State() As Int16
        Get
            Return _Checked
        End Get
        Set(ByVal value As Int16)
            _Checked = value
        End Set
    End Property

    Private Enum MouseState As Integer
        Leave = 0
        Enter = 1
        Down = 2
    End Enum

    Private Enum BtnState As Int16
        ButtonOff = 0
        ButtonOn = 1
        Unused = 2
    End Enum

    Public Sub New()
        Me.SetStyle(ControlStyles.Opaque, False)
        MyBase.BackColor = Color.Transparent
        _mode = Drawing2D.LinearGradientMode.Vertical
        _borderColor = Me.ForeColor
        _borderWidth = 3
        _PointX = 0
        _PointY = 0
        _Color1 = Color.White
        _Color2 = Me.ForeColor
        _Option = 0
        _Checked = BtnState.Unused
        Me.Font = New Font("Arial", 12, FontStyle.Regular)

    End Sub

    Private drawMouseState As MouseState

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Dim gxoff As Graphics
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

        Dim p1, p2, p3, sw, sh, tt, adj, mgn, push As Int16
        If Me.Width < 50 OrElse Me.Height < 50 Then
            p1 = 1 : p2 = 4 : p3 = 3
        Else
            p1 = 2 : p2 = 7 : p3 = 6
        End If
        tt = p1 + p2 + p3 : sw = Me.Width - 1 - tt * 2 : sh = Me.Height - 1 - tt * 2
        adj = _borderWidth / 2
        mgn = 2

        If _bmpOffScreen Is Nothing Then
            _bmpOffScreen = New Bitmap(Me.Width, Me.Height)
        End If
        gxoff = Graphics.FromImage(_bmpOffScreen)
        gxoff.Clear(Me.BackColor)

        Using gp As New GraphicsPath
            gp.StartFigure()

            Dim myPoints As Drawing.Point() = {
                New Drawing.Point(tt + adj, adj),
                New Drawing.Point(tt - adj - mgn + sw, adj),
                New Drawing.Point(tt - adj - mgn + sw + p3, adj + p1),
                New Drawing.Point(tt - adj - mgn + sw + p3 + p2, adj + p1 + p2),
                New Drawing.Point(tt - adj - mgn + sw + p3 + p2 + p1, adj + p1 + p2 + p3),
                New Drawing.Point(tt - adj - mgn + sw + p3 + p2 + p1, -adj - mgn + p1 + p2 + p3 + sh),
                New Drawing.Point(tt - adj - mgn + sw + p3 + p2, -adj - mgn + p1 + p2 + p3 + sh + p3),
                New Drawing.Point(tt - adj - mgn + sw + p3, -adj - mgn + p1 + p2 + p3 + sh + p3 + p2),
                New Drawing.Point(tt - adj - mgn + sw, -adj - mgn + p1 + p2 + p3 + sh + p3 + p2 + p1),
                New Drawing.Point(tt + adj, -adj - mgn + p1 + p2 + p3 + sh + p3 + p2 + p1),
                New Drawing.Point(tt + adj - p3, -adj - mgn + p1 + p2 + p3 + sh + p3 + p2),
                New Drawing.Point(tt + adj - p3 - p2, -adj - mgn + p1 + p2 + p3 + sh + p3),
                New Drawing.Point(tt + adj - p3 - p2 - p1, -adj - mgn + p1 + p2 + p3 + sh),
                New Drawing.Point(tt + adj - p3 - p2 - p1, adj + p1 + p2 + p3),
                New Drawing.Point(tt + adj - p3 - p2, adj + p1 + p2),
                New Drawing.Point(tt + adj - p3, adj + p1)}
            'gp.AddLines(myPoints)
            gp.CloseFigure()


            If _Option = 0 Then
                ' gradation -- 1次元のとき
                Using lgb As New LinearGradientBrush(Me.ClientRectangle, _Color1, _Color2, _mode)
                    lgb.GammaCorrection = True
                    gxoff.FillPolygon(lgb, myPoints)
                End Using
            Else
                ' Pathgradation -- 
                Using lgb As New PathGradientBrush(myPoints)
                    lgb.CenterColor = _Color1
                    lgb.CenterPoint = New Drawing.Point(_PointX, _PointY)
                    lgb.SurroundColors = New Color() {_Color2}
                    gxoff.FillPolygon(lgb, myPoints)
                End Using
            End If

            Using Pen As New Pen(_borderColor, _borderWidth)
                gxoff.DrawPolygon(Pen, myPoints)
            End Using

            ' マウスの状態によりボタンの前景色を変更
            Select Case Me.drawMouseState
                Case MouseState.Enter
                    push = 0
                Case MouseState.Down
                    push = 2
                    Using sb As New SolidBrush(Color.FromArgb(50, _Color2))
                        gxoff.FillPolygon(sb, myPoints)
                    End Using
            End Select

            If _Checked = BtnState.ButtonOn Then
                push = 2
                Using sb As New SolidBrush(Color.FromArgb(50, _Color2))
                    gxoff.FillPolygon(sb, myPoints)
                End Using
            End If

            ' フォーカス枠を描画
            'If Me.Focused = True Then
            'End If
        End Using

        ' 文字列を描画
        Using font As New Font(Me.Font.Name, Me.Font.Size, Me.Font.Style)
            Using sf As New StringFormat
                Select Case Me.TextAlign
                    Case TextAlign.BottomCenter
                        sf.Alignment = StringAlignment.Center
                        sf.LineAlignment = StringAlignment.Far
                    Case TextAlign.BottomLeft
                        sf.Alignment = StringAlignment.Near
                        sf.LineAlignment = StringAlignment.Far
                    Case TextAlign.BottomRight
                        sf.Alignment = StringAlignment.Far
                        sf.LineAlignment = StringAlignment.Far
                    Case TextAlign.MiddleCenter
                        sf.Alignment = StringAlignment.Center
                        sf.LineAlignment = StringAlignment.Center
                    Case TextAlign.MiddleLeft
                        sf.Alignment = StringAlignment.Near
                        sf.LineAlignment = StringAlignment.Center
                    Case TextAlign.MiddleRight
                        sf.Alignment = StringAlignment.Far
                        sf.LineAlignment = StringAlignment.Center
                    Case TextAlign.TopCenter
                        sf.Alignment = StringAlignment.Center
                        sf.LineAlignment = StringAlignment.Near
                    Case TextAlign.TopLeft
                        sf.Alignment = StringAlignment.Near
                        sf.LineAlignment = StringAlignment.Near
                    Case TextAlign.TopRight
                        sf.Alignment = StringAlignment.Far
                        sf.LineAlignment = StringAlignment.Near
                    Case Else
                End Select
                Using sb As New SolidBrush(Me.ForeColor)
                    'Dim strRect As New Rectangle(p1 + p2 + adj, adj + p1 + p2, sw + p3 + p3 - adj - mgn, sh + p3 + p3 - adj - mgn)
                    Dim strRect As New Rectangle(p1 + p2, p1 + p2, sw + p3 + p3 - mgn, sh + p3 + p3 - mgn)
                    gxoff.DrawString(Me.Text, Me.Font, sb, strRect, sf)
                End Using
            End Using
        End Using

        e.Graphics.DrawImage(_bmpOffScreen, push, push)

        Exit Sub

        'MyBase.OnPaint€
    End Sub

    Protected Overrides Sub OnPaintBackground(ByVal pevent As System.Windows.Forms.PaintEventArgs)
        ' do nothing
        MyBase.OnPaintBackground(pevent)
    End Sub

    Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)
        MyBase.OnLeave€
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
        MyBase.OnMouseEnter€
        Me.drawMouseState = MouseState.Enter
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
        MyBase.OnMouseLeave€
        Me.drawMouseState = MouseState.Leave
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseDown(ByVal mevent As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseDown(mevent)
        Me.drawMouseState = MouseState.Down
        If _Checked <> 2 Then
            If _Checked = 0 Then
                _Checked = 1
            Else
                _Checked = 0
            End If
        End If
        'If Me.State <> BtnState.Unused Then
        '    If Me.State = BtnState.ButtonOff Then
        '        Me.State = BtnState.ButtonOn
        '    Else
        '        Me.State = BtnState.ButtonOff
        '    End If
        'End If
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseUp(ByVal mevent As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseUp(mevent)
        If Me.ClientRectangle.Contains(mevent.Location) Then
            Me.drawMouseState = MouseState.Enter
        Else
            Me.drawMouseState = MouseState.Leave
        End If
        Me.Invalidate()
    End Sub

    Private Function BackgroundImageColor(ByVal image As Image) As Color
        Dim bmp As New Bitmap(image)
        Return bmp.GetPixel(0, 0)
    End Function
End Class


上記コードでユーザーコントロールを作成し、プロジェクトに組み込むだけ

【引数】通常のボタンに加え
・BorderWidth・・・縁の幅
・BorderColor ・・・縁の色
・Color1/2・・・・・色1と2
・CenterPoint・・・・色の開始位置
・GOption(グラデーションの種類 Option 0:linear 1:Path)
 0: 線形グラデーション、1:パスグラデーション
・Mode(線形グラデーションのモード(塗りつぶしの向き))
 0:水平 1:垂直 2:Foward 3:Backward
・State(ボタンのState)
 0/1のとき、On/Offの切り替えができる
 2のときは、クリックのみ

【サンプル】・・・特になし

【特記事項】
・VB2015用
・Visual Studio上でデザイン中にボタンのデザインがリアルタイムに反映されません
 とりあえず、デザインビューを開きなおすと表示されます
 原因が分かり次第対応しますが、ご存知の方がいらっしゃいましたらお教えください

  お気軽にご相談ください お問合せ・ご相談はこちら お問合せ・ご相談はこちら  
更新日:2017/02/22 09:28