title: Autoscroll to the bottom of a multiline textbox
body: <p>I have started to make a master-server program for a small project involving rebuilding a game on a newer engine.
  The master server program currently looks like this:</p>
  
  <p><img src="https://i.stack.imgur.com/ABhcB.png" alt="enter image description here"></p>
  
  <p>The large textbox with the 'Found 4 installed processor(s)' is a 'console' which outputs raw event messages sent to and from clients/gameservers using the master-server. It cannot be inputted into and the administrator (<em>the only person who has access to this interface of the master-server program</em>) can only copy from the textbox; they cannot delete/add anything.</p>
  
  <p>The issue is that because it's supposed to be a 'console', it should automatically scroll down to the last line of the multiline textbox.</p>
  
  <p>There are many questions on Stack Overflow which cover this (<a href="https://stackoverflow.com/questions/19728585/autoscroll-to-bottom-of-multiline-textbox-being-updated-by-backgroundworker">this one</a> for example), but I haven't been able to get it working (the textbox doesn't scroll down) when placing the code within the <code>console_TextChanged</code> subroutine.
  I have tried this:</p>
  
  <pre><code>Private Sub console_TextChanged(sender As Object, e As EventArgs) Handles console.TextChanged
      console.AppendText(Text)
      console.Select(console.TextLength, 0)
      console.ScrollToCaret()
  End Sub
  </code></pre>
  
  <p>It doesn't work, but it does however cause a bug in the program where each line is appended with the program's title quite a few times:</p>
  
  <pre><code>[net 11:32:22.243] System Started.Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5Server Network | Crysis Wars 1.5
  </code></pre>
  
  <p>Some C# solutions have also worked for me in Visual Basic .Net in the past, and so I have tried <a href="https://stackoverflow.com/questions/13505248/how-to-make-autoscroll-multiline-textbox-in-winforms">some of the ones on Stack Overflow</a> but I haven't been able to get these working either.</p>
  
  <p>Is this really the correct way to autoscroll a multilined textbox, and if so, why is it not working for me?</p>
  
  <p><strong><em>The complete (relevant) code:</em></strong></p>
  
  <pre><code>Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      console.Text = GetNetTime() + "System Started."
      WriteToConsole("Working Area: " + CStr(My.Computer.Screen.WorkingArea().Width) + "*" + CStr(My.Computer.Screen.WorkingArea().Height))
      WriteToConsole("Found " + CStr(Environment.ProcessorCount) + " installed processor(s)")
      Dim i As Integer = 0
      While (i &lt; Environment.ProcessorCount)
          WriteToConsole("Processor " + CStr(i) + ": " + My.Computer.Registry.LocalMachine.OpenSubKey("Hardware\Description\System\CentralProcessor\" + CStr(i)).GetValue("ProcessorNameString"))
          WriteToConsole("            Family: " + My.Computer.Registry.LocalMachine.OpenSubKey("Hardware\Description\System\CentralProcessor\" + CStr(i)).GetValue("Identifier"))
          WriteToConsole("            Manufacturer: " + My.Computer.Registry.LocalMachine.OpenSubKey("Hardware\Description\System\CentralProcessor\" + CStr(i)).GetValue("VendorIdentifier"))
          i += 1
      End While
      WriteToConsole("Starting networking services")
  End Sub
  Private Sub console_TextChanged(sender As Object, e As EventArgs) Handles console.TextChanged
      console.AppendText(Text)
      console.Select(console.TextLength, 0)
      console.ScrollToCaret()
  End Sub
  Function GetNetTime()
      Return "[net " + CStr(DateTime.UtcNow.Hour) + ":" + CStr(DateTime.UtcNow.Minute) + ":" + CStr(DateTime.UtcNow.Second) + "." + CStr(DateTime.UtcNow.Millisecond) + "] "
  End Function
  Function WriteToConsole(ByVal input As String)
      console.AppendText(Environment.NewLine &amp; GetNetTime() + input)
      Return -1
  End Function
  </code></pre>