When Multiline textboxes and RichText is just too convenient and easy; use a LabelScroller!
It's beta, I still have some edges I need to buff.

This Version:
  • Auto-text adjusting to size and resize
  • AutoScrolling (with custom increments)


Next Version:
  • Reduced flickering by adding and removing specified lines to lblMain
  • Optional "on hover freeze" in auto scrolling
  • Complete Autoscrolling wrap-around (instead of clearing and starting over)


Feel free to drop any more suggestions or let me know of errors you receive.
VB Code:
  1. Public Class LabelScroller
  2.     Inherits System.Windows.Forms.UserControl
  3.  
  4. #Region " Windows Form Designer generated code "
  5.  
  6.     Public Sub New()
  7.         MyBase.New()
  8.  
  9.         'This call is required by the Windows Form Designer.
  10.         InitializeComponent()
  11.  
  12.         'Add any initialization after the InitializeComponent() call
  13.  
  14.     End Sub
  15.  
  16.     'UserControl overrides dispose to clean up the component list.
  17.     Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
  18.         If disposing Then
  19.             If Not (components Is Nothing) Then
  20.                 components.Dispose()
  21.             End If
  22.         End If
  23.         MyBase.Dispose(disposing)
  24.     End Sub
  25.  
  26.     'Required by the Windows Form Designer
  27.     Private components As System.ComponentModel.IContainer
  28.  
  29.     'NOTE: The following procedure is required by the Windows Form Designer
  30.     'It can be modified using the Windows Form Designer.  
  31.     'Do not modify it using the code editor.
  32.     Friend WithEvents lblMain As System.Windows.Forms.Label
  33.     Friend WithEvents vsBar As System.Windows.Forms.VScrollBar
  34.     Friend WithEvents pnlvsBar As System.Windows.Forms.Panel
  35.     Friend WithEvents pnllblMain As System.Windows.Forms.Panel
  36.     <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
  37.         Me.lblMain = New System.Windows.Forms.Label
  38.         Me.vsBar = New System.Windows.Forms.VScrollBar
  39.         Me.pnlvsBar = New System.Windows.Forms.Panel
  40.         Me.pnllblMain = New System.Windows.Forms.Panel
  41.         Me.pnlvsBar.SuspendLayout()
  42.         Me.pnllblMain.SuspendLayout()
  43.         Me.SuspendLayout()
  44.         '
  45.         'lblMain
  46.         '
  47.         Me.lblMain.Dock = System.Windows.Forms.DockStyle.Fill
  48.         Me.lblMain.Location = New System.Drawing.Point(0, 0)
  49.         Me.lblMain.Name = "lblMain"
  50.         Me.lblMain.Size = New System.Drawing.Size(200, 40)
  51.         Me.lblMain.TabIndex = 0
  52.         Me.lblMain.TextAlign = System.Drawing.ContentAlignment.TopCenter
  53.         '
  54.         'vsBar
  55.         '
  56.         Me.vsBar.Dock = System.Windows.Forms.DockStyle.Fill
  57.         Me.vsBar.Location = New System.Drawing.Point(0, 0)
  58.         Me.vsBar.Name = "vsBar"
  59.         Me.vsBar.Size = New System.Drawing.Size(16, 40)
  60.         Me.vsBar.TabIndex = 1
  61.         '
  62.         'pnlvsBar
  63.         '
  64.         Me.pnlvsBar.Controls.Add(Me.vsBar)
  65.         Me.pnlvsBar.Dock = System.Windows.Forms.DockStyle.Right
  66.         Me.pnlvsBar.Location = New System.Drawing.Point(200, 0)
  67.         Me.pnlvsBar.Name = "pnlvsBar"
  68.         Me.pnlvsBar.Size = New System.Drawing.Size(16, 40)
  69.         Me.pnlvsBar.TabIndex = 2
  70.         '
  71.         'pnllblMain
  72.         '
  73.         Me.pnllblMain.Controls.Add(Me.lblMain)
  74.         Me.pnllblMain.Dock = System.Windows.Forms.DockStyle.Fill
  75.         Me.pnllblMain.Location = New System.Drawing.Point(0, 0)
  76.         Me.pnllblMain.Name = "pnllblMain"
  77.         Me.pnllblMain.Size = New System.Drawing.Size(200, 40)
  78.         Me.pnllblMain.TabIndex = 3
  79.         '
  80.         'LabelScroller
  81.         '
  82.         Me.Controls.Add(Me.pnllblMain)
  83.         Me.Controls.Add(Me.pnlvsBar)
  84.         Me.Name = "LabelScroller"
  85.         Me.Size = New System.Drawing.Size(216, 40)
  86.         Me.pnlvsBar.ResumeLayout(False)
  87.         Me.pnllblMain.ResumeLayout(False)
  88.         Me.ResumeLayout(False)
  89.  
  90.     End Sub
  91.  
  92. #End Region
  93.     'Holds lblMain.text property
  94.     Private _Message As String
  95.     Private _arr() As String
  96.  
  97.     'numof lines needed to display message
  98.     Private _NumOfLines As Int32
  99.  
  100.     'Control bounds
  101.     Private _MaxNumOfLines As Int32
  102.     Private _MaxNumOfChars As Int32
  103.  
  104.     'ScrollBar Valus
  105.     Private _VSValue As Int32
  106.  
  107.     'AutoScroll Attributes
  108.     Private _blnScrolling As Boolean
  109.     Private _ScrollInterval As Int32 = 1000
  110.     Private WithEvents _ScrollTimer As Timer
  111.  
  112.     Public Overrides Property Text() As String
  113.         Get
  114.             Return _Message
  115.         End Get
  116.         Set(ByVal Value As String)
  117.             _Message = Value
  118.             Call Makeithappen()
  119.         End Set
  120.     End Property
  121.     Private Sub Makeithappen()
  122.         Call FindLabelBounds()
  123.         Call FindMessageTotalLines()
  124.         Call ProportionvsBar()
  125.         Call PopulatelblMaintext()
  126.     End Sub
  127.  
  128.     Friend Property ScrollInterval() As Int32
  129.         Get
  130.             Return _ScrollInterval
  131.         End Get
  132.         Set(ByVal Value As Int32)
  133.             If _blnScrolling Then
  134.                 Call ScrollStop()
  135.                 _ScrollInterval = Value
  136.                 Call ScrollStart()
  137.             Else
  138.                 _ScrollInterval = Value
  139.             End If
  140.         End Set
  141.     End Property
  142.     Friend Sub ScrollStart()
  143.         _blnScrolling = True
  144.         _ScrollTimer = New Timer
  145.         _ScrollTimer.Interval = _ScrollInterval
  146.         _ScrollTimer.Start()
  147.     End Sub
  148.     Friend Sub ScrollStop()
  149.         _ScrollTimer.Stop()
  150.         _blnScrolling = False
  151.     End Sub
  152.     Private Sub _ScrollTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles _ScrollTimer.Tick
  153.         If _VSValue <> _NumOfLines Then
  154.             vsBar.Value += 1
  155.         Else
  156.             vsBar.Value = 0
  157.         End If
  158.     End Sub
  159.  
  160.     Private Sub FindLabelBounds()
  161.         'Algorithm base(what I tested it against)
  162.         'If labelwidth is 200; the max characters in a line is 31.  Ratio 0.155
  163.         'If labelheight is 40; the max lines is 3.                  Ratio 0.075
  164.         '(Dev Note: screw font)
  165.  
  166.         _MaxNumOfChars = lblMain.Width * 0.155
  167.         _MaxNumOfLines = lblMain.Height * 0.075
  168.     End Sub
  169.     Private Sub FindMessageTotalLines()
  170.         ReDim _arr(0)   'clear it out
  171.  
  172.         Dim arr() As String
  173.         Dim strHold As String
  174.         Dim intLineTotal As Int32 = 0
  175.         If Not _Message Is Nothing Then
  176.             arr = _Message.Split(" ")
  177.  
  178.             For intCnt As Int32 = 0 To UBound(arr)
  179.                 strHold += arr(intCnt) & " "
  180.                 If (strHold.Length > _MaxNumOfChars) Or (intCnt = UBound(arr)) Then
  181.                     intLineTotal += 1
  182.                     ReDim Preserve _arr(intLineTotal)
  183.                     _arr(intLineTotal - 1) = strHold
  184.                     strHold = ""
  185.                 End If
  186.             Next intCnt
  187.             _NumOfLines = intLineTotal
  188.             ReDim Preserve _arr(intLineTotal - 1)
  189.         End If
  190.     End Sub
  191.  
  192.     Private Sub LabelScroller_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Resize
  193.         Call Makeithappen()
  194.     End Sub
  195.     Private Sub PopulatelblMaintext()
  196.         Me.lblMain.Text = ""
  197.         If Not _Message Is Nothing Then
  198.             For intcnt As Int32 = _VSValue To (_VSValue + _MaxNumOfLines) - 1
  199.                 If Not intcnt > UBound(_arr) Then
  200.                     lblMain.Text += _arr(intcnt) & vbNewLine
  201.                 End If
  202.             Next
  203.         End If
  204.     End Sub
  205.  
  206.     Friend ReadOnly Property MaxCharWidth() As Int32
  207.         Get
  208.             Return _MaxNumOfChars
  209.         End Get
  210.     End Property
  211.     Friend ReadOnly Property MaxCharHeight() As Int32
  212.         Get
  213.             Return _MaxNumOfLines
  214.         End Get
  215.     End Property
  216.  
  217.     Private Sub vsBar_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles vsBar.ValueChanged
  218.         _VSValue = CType(sender, Windows.Forms.VScrollBar).Value
  219.         Call PopulatelblMaintext()
  220.     End Sub
  221.     Private Sub ProportionvsBar()
  222.         vsBar.SmallChange = 1
  223.         vsBar.LargeChange = _MaxNumOfLines - 1
  224.  
  225.         If _MaxNumOfLines >= _NumOfLines Then
  226.             vsBar.Enabled = False
  227.         Else
  228.             vsBar.Enabled = True
  229.             vsBar.Maximum = _NumOfLines
  230.             vsBar.Minimum = 0
  231.         End If
  232.     End Sub
  233.  
  234. End Class