Transparent Label Control - Text Refresh Problem

P

post2prabu

I have created a class file for Transparent Label and it works. But
when I placed the control in the form designer, the text inside the
label is not displayed. I have to move the control or press ALT+TAB to
refersh the text. Any tips to overcome this problem?

My Code:

Imports System
Imports System.Windows.Forms.Design
Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Text
Imports System.Windows.Forms

Public Enum Direction
' Fields
AntiClockwise = 1
Clockwise = 0
End Enum

Public Enum Orientation
' Fields
Arc = 1
Circle = 0
Rotate = 2
End Enum


Public Class DesignStaticText
Inherits System.Windows.Forms.Control

' Fields
Private m_rotationAngle As Double
' Private text As String
Private m_textDirection As Direction
Private m_textOrientation As Orientation


<Bindable(False), Browsable(False)> Public Shadows Property
Visible() As Boolean
Get
Return MyBase.Visible
End Get
Set(ByVal Value As Boolean)
MyBase.Visible = Value
End Set
End Property


Public Sub New()
MyBase.SetStyle(ControlStyles.SupportsTransparentBackColor,
True)
Me.m_rotationAngle = 0
Me.m_textOrientation = Orientation.Rotate
Me.BackColor = Color.Transparent


End Sub

Public Sub InvalidateEx()

If (Not MyBase.Parent Is Nothing) Then

Dim rect As Rectangle
rect = New Rectangle(MyBase.Location, MyBase.Size)
MyBase.Parent.Invalidate(rect, True)


Else
End If
Invalidate()
End Sub

Protected Overrides Sub OnFontChanged(ByVal e As EventArgs)
Me.InvalidateEx()
End Sub

'Protected Overrides Sub OnLocationChanged(ByVal e As EventArgs)
' Me.InvalidateEx()
'End Sub

Protected Overrides Sub OnPaintBackground(ByVal pevent As
PaintEventArgs)

End Sub

' Properties
Protected Overrides ReadOnly Property CreateParams() As
CreateParams
Get
Dim params As CreateParams = MyBase.CreateParams
params.ExStyle = (params.ExStyle Or 32)
Return params
End Get
End Property

<Description("Rotation Angle"), Category("Appearance")> _
Public Property RotationAngle() As Double
Get
Return m_rotationAngle
End Get
Set(ByVal value As Double)
m_rotationAngle = value
InvalidateEx()
'MyBase.Invalidate()
End Set
End Property

<Category("Appearance"), Description("Direction of the Text")> _
Public Property TextDirection() As Direction
Get
Return m_textDirection
End Get
Set(ByVal value As Direction)
m_textDirection = value
'MyBase.Invalidate()
InvalidateEx()
End Set
End Property

<Category("Text"), Description("Text to display")> _
Public Overrides Property Text() As String
Get
Return MyBase.Text
End Get
Set(ByVal value As String)
MyBase.Text = value
InvalidateEx()
End Set
End Property
<Category("Appearance"), Description("Kind of Text Orientation")> _
Public Property TextOrientation() As Orientation
Get
Return m_textOrientation
End Get
Set(ByVal value As Orientation)
m_textOrientation = value
InvalidateEx()
End Set
End Property

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim i As Integer

Dim graphics As Graphics = e.Graphics
graphics.SmoothingMode = SmoothingMode.HighQuality
graphics.TextRenderingHint = TextRenderingHint.AntiAlias

Dim stringFormat As StringFormat = New StringFormat
stringFormat.Alignment = StringAlignment.Center
stringFormat.Trimming = StringTrimming.None

Dim textBrush As Brush = New SolidBrush(Me.ForeColor)

'Getting the width and height of the text, which we are going
to write
Dim width As Single = graphics.MeasureString(Text,
Me.Font).Width
Dim height As Single = graphics.MeasureString(Text,
Me.Font).Height

'The radius is set to 0.9 of the width or height, b'cos not to
'hide and part of the text at any stage
Dim radius As Single = 0.0F

If (ClientRectangle.Width < ClientRectangle.Height) Then
radius = ClientRectangle.Width * 0.9F / 2
Else
radius = ClientRectangle.Height * 0.9F / 2
End If


Select Case (m_textOrientation)

Case Orientation.Arc
'Arc angle must be get from the length of the text.
Dim arcAngle As Single = (2 * width / radius) /
Text.Length

If (TextDirection = Direction.Clockwise) Then
For i = 0 To Text.Length - 1
graphics.TranslateTransform(CType((radius * (1
- Math.Cos(arcAngle * i + RotationAngle / 180 * Math.PI))), Single),
CType((radius * (1 - Math.Sin(arcAngle * i + RotationAngle / 180 *
Math.PI))), Single))
graphics.RotateTransform((-90 +
CType(RotationAngle + 180 * arcAngle * i, Single)) / CType(Math.PI,
Single))
graphics.DrawString(Text.Chars(i).ToString(),
Me.Font, textBrush, 0, 0)
graphics.ResetTransform()
Next
Else
For i = 0 To Text.Length - 1
graphics.TranslateTransform(CType((radius * (1
- Math.Cos(arcAngle * i + RotationAngle / 180 * Math.PI))), Single),
CType((radius * (1 + Math.Sin(arcAngle * i + RotationAngle / 180 *
Math.PI))), Single))
graphics.RotateTransform((-90 -
CType(RotationAngle - 180 * arcAngle * i, Single) / CType(Math.PI,
Single)))
graphics.DrawString(Text.Chars(i).ToString(),
Me.Font, textBrush, 0, 0)
graphics.ResetTransform()
Next
End If
Exit Select

Case Orientation.Circle
If (TextDirection = Direction.Clockwise) Then
For i = 0 To Text.Length - 1
graphics.TranslateTransform(CType((radius * (1
- Math.Cos((2 * Math.PI / Text.Length) * i + RotationAngle / 180 *
Math.PI))), Single), CType((radius * (1 - Math.Sin((2 * Math.PI /
Text.Length) * i + RotationAngle / 180 * Math.PI))), Single))
graphics.RotateTransform(-90 +
CType(m_rotationAngle, Single) + (360 / Text.Length) * i)
graphics.DrawString(Text.Chars(i).ToString(),
Me.Font, textBrush, 0, 0)
graphics.ResetTransform()

Next
Else
For i = 0 To Text.Length - 1
graphics.TranslateTransform(CType((radius * (1
- Math.Cos((2 * Math.PI / Text.Length) * i + RotationAngle / 180 *
Math.PI))), Single), CType((radius * (1 + Math.Sin((2 * Math.PI /
Text.Length) * i + RotationAngle / 180 * Math.PI))), Single))
graphics.RotateTransform(-90 -
CType(m_rotationAngle, Single) - (360 / Text.Length) * i)
graphics.DrawString(Text.Chars(i).ToString(),
Me.Font, textBrush, 0, 0)
graphics.ResetTransform()
Next

End If
Exit Select

Case Orientation.Rotate


'For rotation, who about rotation?
Dim angle As Double = (RotationAngle / 180) * Math.PI
graphics.TranslateTransform((ClientRectangle.Width +
CType((height * Math.Sin(angle)), Single) - CType((width *
Math.Cos(angle)), Single)) / 2, (ClientRectangle.Height - CType((height
* Math.Cos(angle)), Single) - CType((width * Math.Sin(angle)), Single))
/ 2)
graphics.RotateTransform(CType(RotationAngle, Single))
graphics.DrawString(Text, Me.Font, textBrush, 0, 0)
graphics.ResetTransform()
Exit Select
End Select


End Sub

Protected Overrides Sub OnLocationChanged(ByVal e As
System.EventArgs)
MyBase.OnLocationChanged(e)
If Not IsNothing(Me.Parent) Then
Me.Parent.Refresh()
End If
End Sub

End Class


Thanks
Prabu Raju
 
P

Phil Wright

Adding the SupportsTransparentBackColor style to your control adds only a
little intelligence to the way it works. Whenever your control is painted it
will automatically ask the parent container (Form, Panel etc...) to paint
itself over your control area before you do your own drawing. So that you
get a transparent effect.

But beware that is another sibling control overlaps your control then the
sibling will not be drawn in the background because only the parent is asked
to paint and not siblings.

Therefore you do not need your code to InvalidateEx to get the parent to
paint itself, this will happen automatically when required. You should not
override the OnPaintBackground either because I would guess that is the very
place that the base class will be asking the parent to paint.

Phil Wright
Follow the startup of my microISV at...
http://componentfactory.blogspot.com
 
B

Bob Powell [MVP]

We have exactly the same problem with a transparent control we're working
on. It works perfectly at runtime but in design mode it's horrible and
requires manual refreshing also. I am investigating some deep designer
mysteries at the moment and will post a solution when and if we find one.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top