BUG: Visual Studio 2012 doesn't theme multiline textbox with initial scrollbar on add-in toolwindow.

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio 2012
Date: October 2012    

This article explains a bug that happens when Visual Studio 2012 themes automatically a toolwindow. If the toolwindow hosts a Windows Forms usercontrol that contains a multiline System.Windows.Forms.TextBox (or System.Windows.Forms.RichTextBox) with the scrollbar set initially (TextBox.Scrollbars = Vertical), the scrollbar is not themed until you write something.

More information

Steps to reproduce the problem:

  • Create a VB.NET add-in with the Connect.vb class below.
Language: VB.NET   Copy Code Copy Code (IE only)
Imports System
Imports Microsoft.VisualStudio.CommandBars
Imports Extensibility
Imports EnvDTE
Imports EnvDTE80
Imports System.Runtime.InteropServices

Public Class Connect
   Implements IDTExtensibility2
   Private _applicationObject As DTE2
   Private _addInInstance As AddIn
   Private _myToolWindow As EnvDTE.Window
   Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, ByVal addInInst As Object, _
      ByRef custom As Array) Implements IDTExtensibility2.OnConnection

      _applicationObject = CType(application, DTE2)
      _addInInstance = CType(addInInst, AddIn)

      Select Case connectMode

         Case ext_ConnectMode.ext_cm_AfterStartup

         Case ext_ConnectMode.ext_cm_Startup
            ' OnStartupComplete will be called

      End Select

   End Sub

   Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete


   End Sub

   Private Sub ShowToolWindow()

      Const TOOLWINDOW_GUID As String = "{6CCD0EE9-20DB-4636-9149-665A958D8A9A}"

      Dim windows2 As EnvDTE80.Windows2
      Dim assembly As String
      Dim myUserControlObject As Object = Nothing
      Dim myUserControl As UserControl1


         If _myToolWindow Is Nothing Then ' First time, create it

            windows2 = DirectCast(_applicationObject.Windows, EnvDTE80.Windows2)

            assembly = System.Reflection.Assembly.GetExecutingAssembly().Location

            _myToolWindow = windows2.CreateToolWindow2(_addInInstance, assembly, _
               GetType(UserControl1).FullName, "My toolwindow", TOOLWINDOW_GUID, myUserControlObject)

            myUserControl = DirectCast(myUserControlObject, UserControl1)
            myUserControl.BackColor = Drawing.Color.FromArgb(37, 37, 38)
            myUserControl.TextBox1.BackColor = myUserControl.BackColor
            myUserControl.TextBox1.ForeColor = Drawing.Color.White

         End If

         _myToolWindow.Visible = True

      Catch e As System.Exception
      End Try

   End Sub

   Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _
      Implements IDTExtensibility2.OnDisconnection
   End Sub

   Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
   End Sub

   Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
   End Sub

End Class
  • Add a UserControl1 to the project, and in the UserControl1.Designer.vb add this code:
Language: VB.NET   Copy Code Copy Code (IE only)
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class UserControl1
    Inherits System.Windows.Forms.UserControl

    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing AndAlso components IsNot Nothing Then
            End If
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
      Me.TextBox1 = New System.Windows.Forms.TextBox()
      Me.TextBox1.Location = New System.Drawing.Point(24, 30)
      Me.TextBox1.Multiline = True
      Me.TextBox1.Name = "TextBox1"
      Me.TextBox1.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
      Me.TextBox1.Size = New System.Drawing.Size(136, 75)
      Me.TextBox1.TabIndex = 0
      Me.TextBox1.Text = "Line 1" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 2" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 3" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 4" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 5" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 6" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 7" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 8" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) _
         & "Line 9"
      Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
      Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
      Me.Name = "UserControl1"
      Me.Size = New System.Drawing.Size(467, 242)

   End Sub
   Friend WithEvents TextBox1 As System.Windows.Forms.TextBox

End Class
  • The add-in shows a toolwindow when loaded. This toolwindow contains a multiline TextBox with some lines of text and a vertical scrollbar that is not themed.

As workaround, to force Visual Studio to theme the scrollbar you can set the TextBox.ScrollBars property to ScrollBars.None and then to ScrollBars.Vertical again.

Go to the 'Visual Studio Extensibility (VSX)' web site for more articles like this (Articles section)