Today I had to draw a text on a panel that I had created at runtime. This is actually pretty easy but there are some pitfalls that can take a few minutes to figure out. This is all still in the good old windows forms, none of that WPF magic for me ;-).
So first you create a form.
And then in the load event of that form we create this.
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- _Panel = New Panel
- _Panel.Dock = DockStyle.Fill
- _Panel.BackColor = Color.LightCyan
- Dim _graphics As Graphics = _Panel.CreateGraphics
- _graphics.DrawString("The brown fox thing.", New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Point, Nothing), New System.Drawing.SolidBrush(Color.Gray), Convert.ToInt32(Me.Width / 2), Convert.ToInt32(Me.Height / 2))
- _Panel.Visible = True
- Me.Controls.Add(_Panel)
- End Sub
Result

Weird no text. Well, I can explain that. If you look very carefully and change your code to this:
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- _Panel = New Panel
- _Panel.Dock = DockStyle.Fill
- _Panel.BackColor = Color.LightCyan
- _Panel.Visible = True
- Me.Controls.Add(_Panel)
- Dim _graphics As Graphics = _Panel.CreateGraphics
- _graphics.DrawString("The brown fox thing.", New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Point, Nothing), New System.Drawing.SolidBrush(Color.Gray), Convert.ToInt32(Me.Width / 2), Convert.ToInt32(Me.Height / 2))
- End Sub
Then you will see whether the text to be drawn quickly disappears or not ;-). What happens is that after you draw the text on the graphics object, the panel is redrawn. The paint event of this panel doesn’t know about the drawstring and doesn’t, therefore, draw it again.
The solution is to draw the string in the paint event of the panel.
Which looks like this:
- Private _Panel As Panel
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- _Panel = New Panel
- _Panel.Dock = DockStyle.Fill
- _Panel.BackColor = Color.LightCyan
- _Panel.Visible = True
- Me.Controls.Add(_Panel)
- AddHandler _Panel.Paint, AddressOf DrawText
- End Sub
- Private Sub DrawText(ByVal obj As Object, ByVal e As PaintEventArgs)
- e.Graphics.DrawString("Rightclick to add or Delete an image.", New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Point, Nothing), New System.Drawing.SolidBrush(Color.Gray), Convert.ToInt32(Me.Width / 2), Convert.ToInt32(Me.Height / 2), string_format)
- End Sub
And this gives this result.

The text isn’t all that beautifully placed but we can do something about that.
Change your code to this:
- Public Class Form1
- Private _Panel As Panel
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- _Panel = New Panel
- _Panel.Dock = DockStyle.Fill
- _Panel.BackColor = Color.LightCyan
- _Panel.Visible = True
- Me.Controls.Add(_Panel)
- AddHandler _Panel.Paint, AddressOf DrawText
- End Sub
- Private Sub DrawText(ByVal obj As Object, ByVal e As PaintEventArgs)
- Using string_format As New StringFormat()
- string_format.Alignment = StringAlignment.Center
- string_format.LineAlignment = StringAlignment.Center
- e.Graphics.DrawString("Rightclick to add or Delete an image.", New Font("Arial", 12, FontStyle.Regular, GraphicsUnit.Point, Nothing), New System.Drawing.SolidBrush(Color.Gray), Convert.ToInt32(Me.ClientSize.Width / 2), Convert.ToInt32(Me.ClientSize.Height / 2), string_format)
- End Using
- End Sub
- End Class
This is the result:

Now the text is nicely centered without having to do to much tedious calculation. The stringformat does most of the hard work for us.
You can find more on this site.
