在自定义控件上发布绘图圆角
Issue Drawing Rounded Corners On Custom Control
我正在尝试创建一个类似于带圆角和边框的长矩形的自定义控件。它还将包含一些文本、一个图标等等,但是当以编程方式添加到我的表单时,我在手动绘制控件时遇到了问题。
代码如下所示:
Option Explicit On
Option Strict On
Imports System.Runtime.InteropServices
Imports Transitions
Imports System.Drawing.Drawing2D
Public Class AlertPanel
Private m_Radius As Integer
Private m_BorderWidth As Integer
Private m_AlertType As AlertType
Private m_Icon As Image
''' <summary>
''' Indicates a Radius of the control's corners
''' </summary>
''' <returns>The corner Radius.</returns>
Public Property Radius As Integer
Get
Return m_Radius
End Get
Set(value As Integer)
m_Radius = value
End Set
End Property
''' <summary>
''' Indicates the width to draw the outer border of the control.
''' </summary>
''' <returns>The border width.</returns>
Public Property BorderWidth As Integer
Get
Return m_BorderWidth
End Get
Set(value As Integer)
m_BorderWidth = value
End Set
End Property
''' <summary>
''' Indicates the type of Alert for the control.
''' </summary>
''' <returns>The Alert type.</returns>
Public Property AlertType As AlertType
Get
Return m_AlertType
End Get
Set(value As AlertType)
m_AlertType = value
End Set
End Property
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Private Sub AlertPanel_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim rect As Rectangle = Me.ClientRectangle 'Drawing Rounded Rectangle
rect.X = rect.X + 1
rect.Y = rect.Y + 1
rect.Width -= 2
rect.Height -= 2
Using bb As GraphicsPath = GetPath(rect, Radius)
'Draw the background
Using br As Brush = New SolidBrush(BackColor)
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic
e.Graphics.FillPath(br, bb)
End Using
'Draw the border
Using br As Brush = New SolidBrush(ForeColor)
rect.Inflate(-1, -1)
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic
e.Graphics.DrawPath(New Pen(br, BorderWidth), bb)
End Using
End Using
End Sub
Protected Function GetPath(ByVal rc As Rectangle, ByVal r As Int32) As GraphicsPath
Dim x As Int32 = rc.X, y As Int32 = rc.Y, w As Int32 = rc.Width, h As Int32 = rc.Height
r = r << 1
Dim path As GraphicsPath = New GraphicsPath()
If r > 0 Then
If (r > h) Then r = h
If (r > w) Then r = w
path.AddArc(x, y, r, r, 180, 90)
path.AddArc(x + w - r, y, r, r, 270, 90)
path.AddArc(x + w - r, y + h - r, r, r, 0, 90)
path.AddArc(x, y + h - r, r, r, 90, 90)
path.CloseFigure()
Else
path.AddRectangle(rc)
End If
Return path
End Function
End Class
然后我这样称呼它:
Dim a As New AlertPanel
With a
.Size = New Size(400, 60)
.Location = New Point(100, 200)
.AlertType = AlertType.Major
.ForeColor = Color.Black
.BorderWidth = 1
.BackColor = Color.IndianRed
.Radius = 10
End With
Me.Controls.Add(a)
我还剩下这个:
更新
根据下面的 Plutonix 对我的代码进行一些编辑后,我现在得到以下结果:
最终更新
最终结果如下所示。非常感谢 Plutonix 的所有帮助!
I am trying to create a custom control
你没有说这是子类化控件(如 Panel)还是构建为 UserControl
。我猜测后者基于 InitializeComponent()
.
最主要的似乎是 UserControl
的标准边框仍在绘制中。添加此以将其关闭:
Public Sub New()
MyBase.BorderStyle = Windows.Forms.BorderStyle.None
...
您可能希望隐藏 属性 以便最终用户无法在“属性”中将其重新打开。
此外,如果边框较宽,您会发现底部边框被裁剪了一个像素(在您的图像中有些明显 - 顶部水平线看起来比底部边框粗)。将此添加到您的 GetPath
方法中:
h As Int32 = rc.Height - 1
结果:
此外,BackColor
被继承并应用于整个客户区,仍然是一个矩形。您可能还需要更换它。将实际的 BackColor
保留为 Transparent
,也许还对用户隐藏 属性,并使用新的 FillColor
属性:
' in the paint event
Using br As Brush = New SolidBrush(FillColor)
...
使用 FillColor
属性 并强制 BackColor
到 Transparent
:
Public Sub ctrlCornerBorder(ctrl As Control, CurveSize As Integer)
Try
Dim p As New System.Drawing.Drawing2D.GraphicsPath
p.StartFigure()
p.AddArc(New Rectangle(0, 0, CurveSize, CurveSize), 180, 90)
'p.AddLine(CurveSize, 0, ctrl.Width - CurveSize, 0)
p.AddArc(New Rectangle(ctrl.Width - CurveSize, 0, CurveSize, CurveSize), -90, 90)
'p.AddLine(ctrl.Width, CurveSize, ctrl.Width, ctrl.Height - CurveSize)
p.AddArc(New Rectangle(ctrl.Width - CurveSize, ctrl.Height - CurveSize, CurveSize, CurveSize), 0, 90)
'p.AddLine(ctrl.Width - 40, ctrl.Height, 40, ctrl.Height)
p.AddArc(New Rectangle(0, ctrl.Height - CurveSize, CurveSize, CurveSize), 90, 90)
p.CloseFigure()
ctrl.Region = New Region(p)
p.Dispose()
Catch ex As Exception
MsgBox(Err.Number & vbCrLf & Err.Description, MsgBoxStyle.Information)
End Try
将此作为 Class 文件并按如下方式调用...
ctrlCornerBorder(pnlList, 15).
这里的 ctrlCornerBorder 是我们的 Class 文件名和 pnlList 作为我们的面板名称 15 是根据您的需要在面板上制作弯曲边缘的值...
我使用绘制事件期间调用的函数在按钮控件上设置了圆角。
- 必须有visual studio,创建一个新项目
- Select 一个新的 windows 表单作为您的新项目
- 向表单添加 2 个按钮
- 双击表格任意位置打开代码window
- 删除所有代码,包括
Form1
子 headers,并粘贴到下面
Imports System.Drawing.Drawing2D
Public Class Form1
Public Sub buttonBorderRadius(ByRef buttonObj As Object, ByVal borderRadiusINT As Integer)
Dim p As New Drawing2D.GraphicsPath()
p.StartFigure()
'TOP LEFT CORNER
p.AddArc(New Rectangle(0, 0, borderRadiusINT, borderRadiusINT), 180, 90)
p.AddLine(40, 0, buttonObj.Width - borderRadiusINT, 0)
'TOP RIGHT CORNER
p.AddArc(New Rectangle(buttonObj.Width - borderRadiusINT, 0, borderRadiusINT, borderRadiusINT), -90, 90)
p.AddLine(buttonObj.Width, 40, buttonObj.Width, buttonObj.Height - borderRadiusINT)
'BOTTOM RIGHT CORNER
p.AddArc(New Rectangle(buttonObj.Width - borderRadiusINT, buttonObj.Height - borderRadiusINT, borderRadiusINT, borderRadiusINT), 0, 90)
p.AddLine(buttonObj.Width - borderRadiusINT, buttonObj.Height, borderRadiusINT, buttonObj.Height)
'BOTTOM LEFT CORNER
p.AddArc(New Rectangle(0, buttonObj.Height - borderRadiusINT, borderRadiusINT, borderRadiusINT), 90, 90)
p.CloseFigure()
buttonObj.Region = New Region(p)
End Sub
Private Sub Button1_Paint(sender As Object, e As PaintEventArgs) Handles Button1.Paint
buttonBorderRadius(sender, 25)
End Sub
Private Sub Button2_Paint(sender As Object, e As PaintEventArgs) Handles Button2.Paint
buttonBorderRadius(sender, 50)
End Sub
End Class
调用函数buttonBorderRadius(sender, 50)
意味着您可以为各个按钮设置不同的borderRadius。
因为它使用 object,您可以将相同的功能应用于图片框和其他控件(虽然不是全部)。
因此您可以使用 buttonBorderRadius(sender, 10)
设置 10 像素的边框半径
和像这样的 50 像素半径 buttonBorderRadius(sender, 50)
只需将整数更改为函数中的第二个参数,
第一个参数必须是 object 变量。
我正在尝试创建一个类似于带圆角和边框的长矩形的自定义控件。它还将包含一些文本、一个图标等等,但是当以编程方式添加到我的表单时,我在手动绘制控件时遇到了问题。
代码如下所示:
Option Explicit On
Option Strict On
Imports System.Runtime.InteropServices
Imports Transitions
Imports System.Drawing.Drawing2D
Public Class AlertPanel
Private m_Radius As Integer
Private m_BorderWidth As Integer
Private m_AlertType As AlertType
Private m_Icon As Image
''' <summary>
''' Indicates a Radius of the control's corners
''' </summary>
''' <returns>The corner Radius.</returns>
Public Property Radius As Integer
Get
Return m_Radius
End Get
Set(value As Integer)
m_Radius = value
End Set
End Property
''' <summary>
''' Indicates the width to draw the outer border of the control.
''' </summary>
''' <returns>The border width.</returns>
Public Property BorderWidth As Integer
Get
Return m_BorderWidth
End Get
Set(value As Integer)
m_BorderWidth = value
End Set
End Property
''' <summary>
''' Indicates the type of Alert for the control.
''' </summary>
''' <returns>The Alert type.</returns>
Public Property AlertType As AlertType
Get
Return m_AlertType
End Get
Set(value As AlertType)
m_AlertType = value
End Set
End Property
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Private Sub AlertPanel_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim rect As Rectangle = Me.ClientRectangle 'Drawing Rounded Rectangle
rect.X = rect.X + 1
rect.Y = rect.Y + 1
rect.Width -= 2
rect.Height -= 2
Using bb As GraphicsPath = GetPath(rect, Radius)
'Draw the background
Using br As Brush = New SolidBrush(BackColor)
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic
e.Graphics.FillPath(br, bb)
End Using
'Draw the border
Using br As Brush = New SolidBrush(ForeColor)
rect.Inflate(-1, -1)
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic
e.Graphics.DrawPath(New Pen(br, BorderWidth), bb)
End Using
End Using
End Sub
Protected Function GetPath(ByVal rc As Rectangle, ByVal r As Int32) As GraphicsPath
Dim x As Int32 = rc.X, y As Int32 = rc.Y, w As Int32 = rc.Width, h As Int32 = rc.Height
r = r << 1
Dim path As GraphicsPath = New GraphicsPath()
If r > 0 Then
If (r > h) Then r = h
If (r > w) Then r = w
path.AddArc(x, y, r, r, 180, 90)
path.AddArc(x + w - r, y, r, r, 270, 90)
path.AddArc(x + w - r, y + h - r, r, r, 0, 90)
path.AddArc(x, y + h - r, r, r, 90, 90)
path.CloseFigure()
Else
path.AddRectangle(rc)
End If
Return path
End Function
End Class
然后我这样称呼它:
Dim a As New AlertPanel
With a
.Size = New Size(400, 60)
.Location = New Point(100, 200)
.AlertType = AlertType.Major
.ForeColor = Color.Black
.BorderWidth = 1
.BackColor = Color.IndianRed
.Radius = 10
End With
Me.Controls.Add(a)
我还剩下这个:
更新
根据下面的 Plutonix 对我的代码进行一些编辑后,我现在得到以下结果:
最终更新
最终结果如下所示。非常感谢 Plutonix 的所有帮助!
I am trying to create a custom control
你没有说这是子类化控件(如 Panel)还是构建为 UserControl
。我猜测后者基于 InitializeComponent()
.
最主要的似乎是 UserControl
的标准边框仍在绘制中。添加此以将其关闭:
Public Sub New()
MyBase.BorderStyle = Windows.Forms.BorderStyle.None
...
您可能希望隐藏 属性 以便最终用户无法在“属性”中将其重新打开。
此外,如果边框较宽,您会发现底部边框被裁剪了一个像素(在您的图像中有些明显 - 顶部水平线看起来比底部边框粗)。将此添加到您的 GetPath
方法中:
h As Int32 = rc.Height - 1
结果:
此外,BackColor
被继承并应用于整个客户区,仍然是一个矩形。您可能还需要更换它。将实际的 BackColor
保留为 Transparent
,也许还对用户隐藏 属性,并使用新的 FillColor
属性:
' in the paint event
Using br As Brush = New SolidBrush(FillColor)
...
使用 FillColor
属性 并强制 BackColor
到 Transparent
:
Public Sub ctrlCornerBorder(ctrl As Control, CurveSize As Integer)
Try
Dim p As New System.Drawing.Drawing2D.GraphicsPath
p.StartFigure()
p.AddArc(New Rectangle(0, 0, CurveSize, CurveSize), 180, 90)
'p.AddLine(CurveSize, 0, ctrl.Width - CurveSize, 0)
p.AddArc(New Rectangle(ctrl.Width - CurveSize, 0, CurveSize, CurveSize), -90, 90)
'p.AddLine(ctrl.Width, CurveSize, ctrl.Width, ctrl.Height - CurveSize)
p.AddArc(New Rectangle(ctrl.Width - CurveSize, ctrl.Height - CurveSize, CurveSize, CurveSize), 0, 90)
'p.AddLine(ctrl.Width - 40, ctrl.Height, 40, ctrl.Height)
p.AddArc(New Rectangle(0, ctrl.Height - CurveSize, CurveSize, CurveSize), 90, 90)
p.CloseFigure()
ctrl.Region = New Region(p)
p.Dispose()
Catch ex As Exception
MsgBox(Err.Number & vbCrLf & Err.Description, MsgBoxStyle.Information)
End Try
将此作为 Class 文件并按如下方式调用...
ctrlCornerBorder(pnlList, 15).
这里的 ctrlCornerBorder 是我们的 Class 文件名和 pnlList 作为我们的面板名称 15 是根据您的需要在面板上制作弯曲边缘的值...
我使用绘制事件期间调用的函数在按钮控件上设置了圆角。
- 必须有visual studio,创建一个新项目
- Select 一个新的 windows 表单作为您的新项目
- 向表单添加 2 个按钮
- 双击表格任意位置打开代码window
- 删除所有代码,包括
Form1
子 headers,并粘贴到下面
Imports System.Drawing.Drawing2D
Public Class Form1
Public Sub buttonBorderRadius(ByRef buttonObj As Object, ByVal borderRadiusINT As Integer)
Dim p As New Drawing2D.GraphicsPath()
p.StartFigure()
'TOP LEFT CORNER
p.AddArc(New Rectangle(0, 0, borderRadiusINT, borderRadiusINT), 180, 90)
p.AddLine(40, 0, buttonObj.Width - borderRadiusINT, 0)
'TOP RIGHT CORNER
p.AddArc(New Rectangle(buttonObj.Width - borderRadiusINT, 0, borderRadiusINT, borderRadiusINT), -90, 90)
p.AddLine(buttonObj.Width, 40, buttonObj.Width, buttonObj.Height - borderRadiusINT)
'BOTTOM RIGHT CORNER
p.AddArc(New Rectangle(buttonObj.Width - borderRadiusINT, buttonObj.Height - borderRadiusINT, borderRadiusINT, borderRadiusINT), 0, 90)
p.AddLine(buttonObj.Width - borderRadiusINT, buttonObj.Height, borderRadiusINT, buttonObj.Height)
'BOTTOM LEFT CORNER
p.AddArc(New Rectangle(0, buttonObj.Height - borderRadiusINT, borderRadiusINT, borderRadiusINT), 90, 90)
p.CloseFigure()
buttonObj.Region = New Region(p)
End Sub
Private Sub Button1_Paint(sender As Object, e As PaintEventArgs) Handles Button1.Paint
buttonBorderRadius(sender, 25)
End Sub
Private Sub Button2_Paint(sender As Object, e As PaintEventArgs) Handles Button2.Paint
buttonBorderRadius(sender, 50)
End Sub
End Class
调用函数buttonBorderRadius(sender, 50)
意味着您可以为各个按钮设置不同的borderRadius。
因为它使用 object,您可以将相同的功能应用于图片框和其他控件(虽然不是全部)。
因此您可以使用 buttonBorderRadius(sender, 10)
设置 10 像素的边框半径
和像这样的 50 像素半径 buttonBorderRadius(sender, 50)
只需将整数更改为函数中的第二个参数,
第一个参数必须是 object 变量。