我正在尝试创建一个类似于带有圆角和边框的长矩形的自定义控件。它还将包含一些文本,一个图标等等,但是当我以编程方式添加到我的表单时,我遇到了手动绘制控件的问题。
代码如下:
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提供的所有帮助!
答案 0 :(得分:2)
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
:
答案 1 :(得分:0)
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
将此作为一个类文件并调用Like This as Follows ...
ctrlCornerBorder(pnlList,15)。
这里ctrlCornerBorder是我们的类文件名和pnlList因为我们的面板名称和15是根据你需要在面板上制作曲线边缘而改变的值...
答案 2 :(得分:0)
我使用在绘制事件期间调用的函数在按钮控件上获得了圆角。
Form1
子标题,然后粘贴到下面的
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。
因为它使用了对象,你可以将相同的功能应用于图片框和其他控件(不是全部)。
因此您可以使用buttonBorderRadius(sender, 10)
设置10像素的边框半径
和像这样buttonBorderRadius(sender, 50)
的50像素半径
只需将整数更改为函数中的第二个参数,
第一个参数必须是对象变量。