Richard C Richard C - 2 months ago 17x Question

Custom Control Text Missing

I have a custom control which is supposed to represent a label, but with rounded corners. I've created the control so it is drag and drop from the Designer Toolbox, rounded the top corners, but the Text seems to dissapear.

I know I can add another custom Property for the Text which will show at the bottom, but the Text Property is already there and ideally I would like to use it. I thought I could do it using an Override Property, but at the minute it still doesn't show.

Any suggestions, I've copied my code below...

Imports System.Windows.Forms.Design
Imports System.Runtime.InteropServices
Imports System.Drawing.Drawing2D
Imports System.ComponentModel

Public Class CustomControl
Inherits System.Windows.Forms.UserControl
Private m_Radius As Integer
Private m_BorderWidth As Integer
Private m_FillColor As Color
Private m_Text As String = Me.Text
Private m_Label As Label

Private components As System.ComponentModel.Container = Nothing

Public Sub New()

MyBase.BorderStyle = Windows.Forms.BorderStyle.None
End Sub

''' <summary>
''' Indicates a Radius of the control's corners
''' </summary>
''' <returns>The corner Radius.</returns>
Public Property Radius As Integer
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
Return m_BorderWidth
End Get
Set(value As Integer)
m_BorderWidth = value
End Set
End Property

''' <summary>
''' Indicates the outline colour of the control.
''' </summary>
''' <returns>The outline colour.</returns>
Public Property FillColor As Color
Return m_FillColor
End Get
Set(value As Color)
m_FillColor = value
End Set
End Property

<Browsable(True), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
Overrides Property Text() As String
Return m_Text
End Get
Set(ByVal value As String)
m_Text = value
'This line just for update
'the UI when I design to check
'if the values are saved.
MyBase.Text = value
End Set
End Property

Protected Overrides Sub onPaint(e As PaintEventArgs)
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(FillColor)
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear
e.Graphics.FillPath(br, bb)
End Using
'Draw the border
Using br As Brush = New SolidBrush(Color.Black)
rect.Inflate(-1, -1)
e.Graphics.SmoothingMode = SmoothingMode.HighQuality
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBilinear
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 - 1, h As Int32 = rc.Height - 1
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

' Top Left
path.AddArc(x, y, r, r, 180, 90)

' Top Right
path.AddArc(x + w - r, y, r, r, 270, 90)

'Bottom Right
'path.AddArc(x + w - r, y + h - r, r, r, 0, 90)
path.AddLine(x + w, y + h, x + w, y + h)

' Bottom Left
' path.AddArc(x, y + h - r, r, r, 90, 90)
path.AddLine(x, y + h, x, y + h)

End If
Return path
End Function

End Class



You are only drawing the borders in the OnPaint override and not the text. At the bottom add:

TextRenderer.DrawText(e.Graphics, m_Text, Me.Font, 
                     New Point(3, 3), Me.ForeColor)

This draws to the fixed point 3,3, but you may want to add code to calculate the location based on a TextAlign property (ToDo) or at least based on the Padding values.

If you want it to redraw the text at design time when you change it, you'll also have to add Me.Invalidate() to the Text property setter.