This article explains how to add a control to a Windows form from a
Visual Studio add-in.
For windows that contain a Windows Forms designer, the Window.Object property
returns a System.ComponentModel.Design.IDesignerHost object that can be used to
call its CreateComponent method. This method has two overloaded variations: one
of them receives the component type and its name, while the other receives only
the component type and the name is generated automatically. In order to appear
in the form, you must also set the "Parent" property of the new control to the
form (IDesignerHost.RootComponent). To set the property of a control you must
use a PropertyDescriptor to get the property value serialized, rather than manipulating directly the properties of
the component. The following add-in shows how to add a ListView with a
ColumnHeader:
Private m_objDTE As DTE
Public Sub OnConnection(ByVal Application As Object, _
ByVal ConnectMode As Extensibility.ext_ConnectMode, _
ByVal AddInInst As Object, ByRef custom As System.Array) _
Implements Extensibility.IDTExtensibility2.OnConnection
Try
Select Case ConnectMode
Case ext_ConnectMode.ext_cm_Startup, ext_ConnectMode.ext_cm_AfterStartup
m_objDTE = CType(Application, DTE)
If Not (m_objDTE.ActiveDocument Is Nothing) Then
' Check if the active document window is a Windows Form designer
If TypeOf m_objDTE.ActiveDocument.ActiveWindow.Object Is _
System.ComponentModel.Design.IDesignerHost Then
AddListViewWithColumnHeader(m_objDTE.ActiveDocument.ActiveWindow)
End If
End If
End Select
Catch objException As Exception
MessageBox.Show(objException.ToString)
End Try
End Sub
Private Sub AddListViewWithColumnHeader(ByVal objWindow As EnvDTE.Window)
Dim objIDesignerHost As IDesignerHost
Dim objIComponent As IComponent
Dim objPropertyDescriptor As PropertyDescriptor
Dim colColumns As ListView.ColumnHeaderCollection
Dim objColumnHeader As ColumnHeader
Dim objIComponentInitializer As IComponentInitializer
' The window should be a Form or Usercontrol window in design view. Get its designer host
objIDesignerHost = DirectCast(objWindow.Object, IDesignerHost)
' Create a new ListView with name "ListView1"
Try
objIComponent = objIDesignerHost.CreateComponent(GetType(ListView), "ListView1")
Catch ex As Exception
End Try
' Set its parent to the form (root component). Notice that you must use a PropertyDescriptor
objPropertyDescriptor = System.ComponentModel.TypeDescriptor.GetProperties(objIComponent).Item("Parent")
objPropertyDescriptor.SetValue(objIComponent, objIDesignerHost.RootComponent)
' Create a new empty ColumnHeaderCollection
colColumns = New ListView.ColumnHeaderCollection(DirectCast(objIComponent, ListView))
' Create a new ColumnHeader with name "ColumnHeader1". Notice that you should not create a ColumnHeader directly with the New operator
objColumnHeader = DirectCast(objIDesignerHost.CreateComponent(GetType(ColumnHeader), "ColumnHeader1"), ColumnHeader)
' Make the designer to initialize the new component with empty default values
objIComponentInitializer = TryCast(objIDesignerHost.GetDesigner(objColumnHeader), IComponentInitializer)
If (Not objIComponentInitializer Is Nothing) Then
objIComponentInitializer.InitializeNewComponent(defaultValues:=Nothing)
End If
' Set some column header properties. In this case a PropertyDescriptor is not needed
objColumnHeader.Text = "Column 1"
' Add the column header to the collection
colColumns.Add(objColumnHeader)
' Set the new column header collection to the listview. Notice that you must use a PropertyDescriptor
objPropertyDescriptor = TypeDescriptor.GetProperties(objIComponent).Item("Columns")
objPropertyDescriptor.SetValue(objIComponent, colColumns)
End Sub