Vertical scrolling textbox (animated aboutbox)
A usercontrol to display vertical scrolled text. By example for an about box.
Introduction
This article explains the usage and the source code of the usercontrol.
Background
Some years ago I needed a control been able to scroll text vertically. I needed this for an About-Form to present some credits. I found a basic solution by an author of an article named Paul Pickert on the page of planet-source-code.com. At present my requirements changed an I had to enhance the features of that basic solution.
Please be patient for language mistakes because English is not my native language.
Using the code
I like to divide the article into to parts. Part 1 explains the usage of the control by the developer. Part 2 the code structure and the basics behind.
Part 1: Control usage
The Properties setup:
Now you are ready to set the properties. In addition to the known properties of a usercontrol you may find
two new properties Message
and MessageTimer
. They may also be found under the new
category "extended properties" of the property page.
This two properties are representing two child controls of the user control.
Message
represents a label control and MessageTimer
a standard timer control. Use the properties of this child controls and the main properties of the usercontrol to design your
animatedTexbox
control.
Message.Text
: holds the the scrolling text, lines may divided by vbCRlfMessage.TextAlign
: aligns the scrolling textMessageTimer.Interval
: scrolling Interval in milliseconds. 50ms should be good.MessageTimer.Enabled
: start/stop of scrolling
That's all!
Preparing the Windows Form that hosts the control:
Now we have to initialize the control when the parent form loads. We do this within the load event of the form, see code listing area.
Private Sub frmAbout_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' define the text for the message. Use vbCrlf for carriage return/new line
Dim strMessage As String = "Copyright fremde Programm Controls:" & vbCrLf
strMessage = strMessage & "(Taken form codeproject.com)" & vbCrLf & vbCrLf
strMessage = strMessage & "ImageView Control by Jordy Ruiter" & vbCrLf
strMessage = strMessage & "MultiColCombobox by Gismo" & vbCrLf
strMessage = strMessage & "CustValidatorTextbox by Vivek Bhatnagar" & vbCrLf
' ini the control property values
animTextBox1.Message.Text = strMessage ' set the message text
' set no TextAlign to use the default center alignment
' set no timer interval to use the default value of 50 milliseconds
animTextBox1.MessageTimer.Enabled = True 'start animation
End Sub
Part 2: "The Controls Code"
- Go and create an new project, choose Visual Basic as the language and type Windows Usercontrol.
- Rename the usercontrol name and give it the name
animTextbox
. This name must be used, otherwise you will have a conflict using the helper classes for the toolbox icon (see description as follows). - Create 16x16 pixel bitmap (bmp) as the toolbox item bitmap and place file in the project folder. The name must be animToolbox.bmp.
- Open the usercontrol in the designer.
- Drag a panel control on it and set its Dock property to fill. Name it
Panel1
. - Drag a label control onto the panel control and set its position to the footer of the panel, name it
labelMessage
. - Open the code window of the usercontrol.
I divided the code into regions for better readability.
In the code header of the usercontrol we have to define the reference to import of the
System.ComponentModel
. We need this import for defining the extended usercontrol properties.
' ### neccessary Imports
Imports System.ComponentModel
Next we have to define the code for the toolbox icon. This code is tied to the opening class statement. The code references two classes you have to attached to the usercontrols project. This helper classes are used to show the icon in the visual studio toolbox correctly. Please use them as the are. The content of the classes is not explained within this article because they are only helper classes.
' set the Toolbox Bitmap Icon
' this done by the classes classToolboxIcon and clsTypeConverter
<ToolboxItem(True)> <ToolboxBitmap(GetType(animTextBoxToolboxitem), "animTextBox.bmp")> _
Public Class animTextBox
Next line under the opening class statement we define some global variables and for the animation we need a timer object.
#Region "INI Variables, objects, events" ' ################
' ## Property variables
Private _Msg As Label = LabelMessage
Private _TMR As Timer
' ## other variables
Private intPosition = 0
' ## Private objects
Private WithEvents objTimer1 As New Timer ' use withevents to get timer tick event
#End Region
We will define the _Msg
and _TMR
variable as controls. This simple trick gives us the possibility to make the properties of this controls transparent through the usercontrol. Due to this the control user is able to modifiy the properties. If we will not do so the usercontrol only shows its own properties.
Now we can concentrate of defining some extra properties to enhance the standard properties of the usercontrol:
#Region "extended usercontrol properties" ' ###########
' public all label object properties to be able to change them
<Browsable(True), Description("Textlabel of the message to hold the message text") _
, Category("extended Properties")> _
Public Property Message As Label
Get
Return LabelMessage
End Get
Set(value As Label)
_Msg = value
End Set
End Property
' public all timer object properties to be able to change them
<Browsable(True), Description("Timer for animation of the message") _
, Category("extended Properties")> _
Public Property MessageTimer As Timer
Get
Return objTimer1
End Get
Set(value As Timer)
_TMR = value
End Set
End Property
#End Region
The first Property Message holds the usercontrol
child control object labelMessage
and the property MessageTimer
the internal timer object.
The next step is defining the controls events:
In the load event we will
populate the property variables _Msg
and _TMR
with the controls. At least we call the
internal function ALignText()
to make sure the scrolled text is aligned as requested..
#Region "Control events" '#########################
' Event control loads
' set startup values
Private Sub animTextBox_Load(sender As Object, e As EventArgs) Handles Me.Load
intPosition = Panel1.Height + 25 ' set initial start position
_TMR = objTimer1 ' load property value with timer object
_Msg = LabelMessage ' load property value with label object
' 50 (Milliseconds) should be a good timer.interval value for a smooth
' animation
objTimer1.Interval = 50
ALignText() ' reset text alignment
End Sub
To managed the animation of the text we use the timer tick Event. To animate/scroll the text we start by setting the
labelMessage.Top
position outside (below) of the Panel1
control. Therefore it is not visible at the beginning.
Each timer tick we subtract 1 from the Top position value to force the
labelMessage
control to be redrawn 1 point higher to the top of the
Panel1
control. This looks like an upward scrolling. We do so as long as the complete
labelMessage
Control is outside (above) the the Panel1
control.
Therefore the labelMessage
control is not visible.
If we reach this point we reset the position of the
labelMessage
control back to its start values. This mimics an endless scrolling text.
At least we call
Application.DoEvents
to release all pending application tasks that may be on hold during the timer
tick task.
' Event timer tick = next animation step
Private Sub objTimer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles objTimer1.Tick
On Error Resume Next
' if there is no message text stop timer
If LabelMessage.Text = "" Then
objTimer1.Enabled = False
Else
' increase/scroll label top point
intPosition = intPosition - 1
' check if label is completly scrolled
' if yes reset label top position below panel to restart animation
If intPosition = (LabelMessage.Height + 25) * -1 Then
LabelMessage.Top = Me.Height + 25
intPosition = LabelMessage.Top
End If
' show label at new postion
LabelMessage.Top = intPosition
End If
ALignText() ' make shure text alignment
Application.DoEvents() ' give other app tasks a chance to work
End Sub
To give the user of the application a chance to stop the scrolling may be for reading the static text we offer him the possibility do do so by pointing with the mouse cursor on the usercontrol area. To define this we use the
Mouse.Enter
and Mouse. leave events of the Panel1
control. ' Event cursor is entering/inside panel/control area
' stop the animation and set text to top
Private Sub Panel1_MouseEnter(sender As Object, e As EventArgs) Handles Panel1.MouseEnter
' stop the timer and set the label.top position to the top of the panel
objTimer1.Enabled = False
LabelMessage.Top = Me.Height - 50
ALignText()
End Sub
' Event cursor is leaving panel/control area
' restart the animation
Private Sub Panel1_MouseLeave(sender As Object, e As EventArgs) Handles Panel1.MouseLeave
' reset the label.top position below the panel to restart animation
LabelMessage.Top = Me.Height + 25
intPosition = LabelMessage.Top
objTimer1.Enabled = True
End Sub
#End Region
Uff, we are coming to the rest of all that work. We have to define the function
AlignText()
. This will put the labelMessage
Control to the left Border of the Panel1
control (left align) or it will center it.
#Region "Private Functions/Subs" '#################
' Align the Textposition
Sub ALignText()
On Error Resume Next
' if the TextAlign property of the text label is set to left
' put the text label control to the left border of its parent (panel)
If LabelMessage.TextAlign = ContentAlignment.TopLeft Then
LabelMessage.Left = 1
Else ' if not always center the text label (panel dock property is set to fill)
Dim intW As Integer = Int(Me.Width / 2)
Dim intW1 As Integer = Int(LabelMessage.Width / 2)
Dim intDiff = intW - intW1
If intDiff < 0 Then intDiff = 0 ' avoid negativ values
LabelMessage.Left = intDiff
End If
End Sub
#End Region
end class
You are ready! Compile the project and use the created (animTextbox Control) DLL in your next projects.
To download a ZIP File with the Visual Studio Project use this Link: Download VerticalText.zip
Points of Interest
I traveled around in the internet an I found some solutions. In most cases they draw the text by using GDI functionality. I tried them and had the known flickering problem. Than I remembered the solution of Paul Pickert I found years ago which is a very simple Idea. At the end I learned that sometimes the simple solutions are the best way to go.
History
No updates yet because this is the initial version. If you may find bugs or have an idea to make things better please feel free to comment.