110,539
社区成员
发帖
与我相关
我的任务
分享
Friend Sub RenderBackgroundInternal(ByVal g As Graphics, ByVal rect As Rectangle, ByVal baseColor As Color, ByVal borderColor As Color, ByVal innerBorderColor As Color, ByVal style As RoundStyle, _
ByVal roundWidth As Integer, ByVal basePosition As Single, ByVal drawBorder As Boolean, ByVal drawGlass__1 As Boolean, ByVal mode As LinearGradientMode)
If drawBorder Then
rect.Width -= 1
rect.Height -= 1
End If
Using brush As New LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode)
Dim colors As Color() = New Color(3) {}
colors(0) = GetColor(baseColor, 0, 35, 24, 9)
colors(1) = GetColor(baseColor, 0, 13, 8, 3)
colors(2) = baseColor
colors(3) = GetColor(baseColor, 0, 68, 69, 54)
Dim blend As New ColorBlend()
blend.Positions = New Single() {0.0F, basePosition, basePosition + 0.05F, 1.0F}
blend.Colors = colors
brush.InterpolationColors = blend
If style <> RoundStyle.None Then
Using path As GraphicsPath = GraphicsPathHelper.CreatePath(rect, roundWidth, style, False)
g.FillPath(brush, path)
End Using
If baseColor.A > 80 Then
Dim rectTop As Rectangle = rect
If mode = LinearGradientMode.Vertical Then
rectTop.Height = CInt(Math.Truncate(rectTop.Height * basePosition))
Else
rectTop.Width = CInt(Math.Truncate(rect.Width * basePosition))
End If
Using pathTop As GraphicsPath = GraphicsPathHelper.CreatePath(rectTop, roundWidth, RoundStyle.Top, False)
Using brushAlpha As New SolidBrush(Color.FromArgb(80, 255, 255, 255))
g.FillPath(brushAlpha, pathTop)
End Using
End Using
End If
If drawGlass__1 Then
Dim glassRect As RectangleF = rect
If mode = LinearGradientMode.Vertical Then
glassRect.Y = rect.Y + rect.Height * basePosition
glassRect.Height = (rect.Height - rect.Height * basePosition) * 2
Else
glassRect.X = rect.X + rect.Width * basePosition
glassRect.Width = (rect.Width - rect.Width * basePosition) * 2
End If
DrawGlass(g, glassRect, 170, 0)
End If
If drawBorder Then
Using path As GraphicsPath = GraphicsPathHelper.CreatePath(rect, roundWidth, style, False)
Using pen As New Pen(borderColor)
g.DrawPath(pen, path)
End Using
End Using
rect.Inflate(-1, -1)
Using path As GraphicsPath = GraphicsPathHelper.CreatePath(rect, roundWidth, style, False)
Using pen As New Pen(innerBorderColor)
g.DrawPath(pen, path)
End Using
End Using
End If
Else
g.FillRectangle(brush, rect)
If baseColor.A > 80 Then
Dim rectTop As Rectangle = rect
If mode = LinearGradientMode.Vertical Then
rectTop.Height = CInt(Math.Truncate(rectTop.Height * basePosition))
Else
rectTop.Width = CInt(Math.Truncate(rect.Width * basePosition))
End If
Using brushAlpha As New SolidBrush(Color.FromArgb(80, 255, 255, 255))
g.FillRectangle(brushAlpha, rectTop)
End Using
End If
If drawGlass__1 Then
Dim glassRect As RectangleF = rect
If mode = LinearGradientMode.Vertical Then
glassRect.Y = rect.Y + rect.Height * basePosition
glassRect.Height = (rect.Height - rect.Height * basePosition) * 2
Else
glassRect.X = rect.X + rect.Width * basePosition
glassRect.Width = (rect.Width - rect.Width * basePosition) * 2
End If
DrawGlass(g, glassRect, 200, 0)
End If
If drawBorder Then
Using pen As New Pen(borderColor)
g.DrawRectangle(pen, rect)
End Using
rect.Inflate(-1, -1)
Using pen As New Pen(innerBorderColor)
g.DrawRectangle(pen, rect)
End Using
End If
End If
End Using
End Sub
Private Sub DrawGlass(ByVal g As Graphics, ByVal glassRect As RectangleF, ByVal alphaCenter As Integer, ByVal alphaSurround As Integer)
DrawGlass(g, glassRect, Color.White, alphaCenter, alphaSurround)
End Sub
Private Sub DrawGlass(ByVal g As Graphics, ByVal glassRect As RectangleF, ByVal glassColor As Color, ByVal alphaCenter As Integer, ByVal alphaSurround As Integer)
Using path As New GraphicsPath()
path.AddEllipse(glassRect)
Using brush As New PathGradientBrush(path)
brush.CenterColor = Color.FromArgb(alphaCenter, glassColor)
brush.SurroundColors = New Color() {Color.FromArgb(alphaSurround, glassColor)}
brush.CenterPoint = New PointF(glassRect.X + glassRect.Width / 2, glassRect.Y + glassRect.Height / 2)
g.FillPath(brush, path)
End Using
End Using
End Sub
Private Function GetColor(ByVal colorBase As Color, ByVal a As Integer, ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As Color
Dim a0 As Integer = colorBase.A
Dim r0 As Integer = colorBase.R
Dim g0 As Integer = colorBase.G
Dim b0 As Integer = colorBase.B
If a + a0 > 255 Then
a = 255
Else
a = Math.Max(a + a0, 0)
End If
If r + r0 > 255 Then
r = 255
Else
r = Math.Max(r + r0, 0)
End If
If g + g0 > 255 Then
g = 255
Else
g = Math.Max(g + g0, 0)
End If
If b + b0 > 255 Then
b = 255
Else
b = Math.Max(b + b0, 0)
End If
Return Color.FromArgb(a, r, g, b)
End Function
Friend Shared Function GetTextFormatFlags(ByVal alignment As ContentAlignment, ByVal rightToleft As Boolean) As TextFormatFlags
Dim flags As TextFormatFlags = TextFormatFlags.WordBreak Or TextFormatFlags.SingleLine
If rightToleft Then
flags = flags Or TextFormatFlags.RightToLeft Or TextFormatFlags.Right
End If
Select Case alignment
Case ContentAlignment.BottomCenter
flags = flags Or TextFormatFlags.Bottom Or TextFormatFlags.HorizontalCenter
Exit Select
Case ContentAlignment.BottomLeft
flags = flags Or TextFormatFlags.Bottom Or TextFormatFlags.Left
Exit Select
Case ContentAlignment.BottomRight
flags = flags Or TextFormatFlags.Bottom Or TextFormatFlags.Right
Exit Select
Case ContentAlignment.MiddleCenter
flags = flags Or TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter
Exit Select
Case ContentAlignment.MiddleLeft
flags = flags Or TextFormatFlags.VerticalCenter Or TextFormatFlags.Left
Exit Select
Case ContentAlignment.MiddleRight
flags = flags Or TextFormatFlags.VerticalCenter Or TextFormatFlags.Right
Exit Select
Case ContentAlignment.TopCenter
flags = flags Or TextFormatFlags.Top Or TextFormatFlags.HorizontalCenter
Exit Select
Case ContentAlignment.TopLeft
flags = flags Or TextFormatFlags.Top Or TextFormatFlags.Left
Exit Select
Case ContentAlignment.TopRight
flags = flags Or TextFormatFlags.Top Or TextFormatFlags.Right
Exit Select
End Select
Return flags
End Function
End Class
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.ComponentModel
Public Class buttonEx
Inherits Button
Private _baseColor As Color = Color.FromArgb(160, 199, 223)
Private _controlState As ControlState
Private _imageWidth As Integer = 18
Private _roundStyle As RoundStyle = RoundStyle.All
Private _radius As Integer = 8
Public Sub New()
MyBase.New()
SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw Or ControlStyles.SupportsTransparentBackColor, True)
End Sub
<DefaultValue(GetType(Color), "160, 199, 223")> _
Public Property BaseColor() As Color
Get
Return _baseColor
End Get
Set(ByVal value As Color)
_baseColor = value
MyBase.Invalidate()
End Set
End Property
<DefaultValue(18)> _
Public Property ImageWidth() As Integer
Get
Return _imageWidth
End Get
Set(ByVal value As Integer)
If Value <> _imageWidth Then
_imageWidth = If(Value < 12, 12, Value)
MyBase.Invalidate()
End If
End Set
End Property
<DefaultValue(GetType(RoundStyle), "1")> _
Public Property RoundStyle() As RoundStyle
Get
Return _roundStyle
End Get
Set(ByVal value As RoundStyle)
If _roundStyle <> Value Then
_roundStyle = Value
MyBase.Invalidate()
End If
End Set
End Property
<DefaultValue(8)> _
Public Property Radius() As Integer
Get
Return _radius
End Get
Set(ByVal value As Integer)
If _radius <> Value Then
_radius = If(Value < 4, 4, Value)
MyBase.Invalidate()
End If
End Set
End Property
Friend Property ControlState() As ControlState
Get
Return _controlState
End Get
Set(ByVal value As ControlState)
If _controlState <> Value Then
_controlState = Value
MyBase.Invalidate()
End If
End Set
End Property
Protected Overrides Sub OnMouseEnter(ByVal e As EventArgs)
MyBase.OnMouseEnter(e)
ControlState = ControlState.Hover
End Sub
Protected Overrides Sub OnMouseLeave(ByVal e As EventArgs)
MyBase.OnMouseLeave(e)
ControlState = ControlState.Normal
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
MyBase.OnMouseDown(e)
If e.Button = MouseButtons.Left AndAlso e.Clicks = 1 Then
ControlState = ControlState.Pressed
End If
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
MyBase.OnMouseUp(e)
If e.Button = MouseButtons.Left AndAlso e.Clicks = 1 Then
If ClientRectangle.Contains(e.Location) Then
ControlState = ControlState.Hover
Else
ControlState = ControlState.Normal
End If
End If
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
MyBase.OnPaintBackground(e)
Dim g As Graphics = e.Graphics
Dim imageRect As Rectangle
Dim textRect As Rectangle
CalculateRect(imageRect, textRect)
g.SmoothingMode = SmoothingMode.AntiAlias
Dim baseColor As Color
Dim borderColor As Color
Dim innerBorderColor As Color = Color.FromArgb(200, 255, 255, 255)
If Enabled Then
Select Case ControlState
Case ControlState.Hover
baseColor = GetColor(_baseColor, 0, -13, -8, -3)
borderColor = _baseColor
Exit Select
Case ControlState.Pressed
baseColor = GetColor(_baseColor, 0, -35, -24, -9)
borderColor = _baseColor
Exit Select
Case Else
baseColor = _baseColor
borderColor = _baseColor
Exit Select
End Select
Else
'禁用背景和边框颜色
baseColor = Color.FromArgb(255, 255, 255)
borderColor = Color.FromArgb(56, 134, 207)
End If
RenderBackgroundInternal(g, ClientRectangle, baseColor, borderColor, innerBorderColor, RoundStyle, _
Radius, 0.35F, True, True, LinearGradientMode.Vertical)
If Image IsNot Nothing Then
g.InterpolationMode = InterpolationMode.HighQualityBilinear
g.DrawImage(Image, imageRect, 0, 0, Image.Width, Image.Height, _
GraphicsUnit.Pixel)
End If
TextRenderer.DrawText(g, Text, Font, textRect, ForeColor, GetTextFormatFlags(TextAlign, RightToLeft = RightToLeft.Yes))
End Sub
Private Sub CalculateRect(ByRef imageRect As Rectangle, ByRef textRect As Rectangle)
imageRect = Rectangle.Empty
textRect = Rectangle.Empty
If Image Is Nothing Then
textRect = New Rectangle(2, 0, Width - 4, Height)
Return
End If
Select Case TextImageRelation
Case TextImageRelation.Overlay
imageRect = New Rectangle(2, (Height - ImageWidth) \ 2, ImageWidth, ImageWidth)
textRect = New Rectangle(2, 0, Width - 4, Height)
Exit Select
Case TextImageRelation.ImageAboveText
imageRect = New Rectangle((Width - ImageWidth) \ 2, 2, ImageWidth, ImageWidth)
textRect = New Rectangle(2, imageRect.Bottom, Width, Height - imageRect.Bottom - 2)
Exit Select
Case TextImageRelation.ImageBeforeText
imageRect = New Rectangle(2, (Height - ImageWidth) \ 2, ImageWidth, ImageWidth)
textRect = New Rectangle(imageRect.Right + 2, 0, Width - imageRect.Right - 4, Height)
Exit Select
Case TextImageRelation.TextAboveImage
imageRect = New Rectangle((Width - ImageWidth) \ 2, Height - ImageWidth - 2, ImageWidth, ImageWidth)
textRect = New Rectangle(0, 2, Width, Height - imageRect.Y - 2)
Exit Select
Case TextImageRelation.TextBeforeImage
imageRect = New Rectangle(Width - ImageWidth - 2, (Height - ImageWidth) \ 2, ImageWidth, ImageWidth)
textRect = New Rectangle(2, 0, imageRect.X - 2, Height)
Exit Select
End Select
If RightToLeft = RightToLeft.Yes Then
imageRect.X = Width - imageRect.Right
textRect.X = Width - textRect.Right
End If
End Sub