Embedding a WPF User Control in a DockableWindow in Inventor

By Barbara Han

If you have a Windows Form containing an ElementHost control and the ElementHost containing a WPF UserControl, then assign this form as a child of a DockableWindow, you can get a dockable window that shows WPF control in Inventor.

The following is main VB.NET code snippet:

StandardAddInServer.vb:

Imports Inventor

Imports System.Runtime.InteropServices

Imports Microsoft.Win32

Imports System.Windows.Forms

 

Namespace vbButton

  <ProgIdAttribute("vbButton.StandardAddInServer"), _

  GuidAttribute("f00de0d0-9de0-46fb-ac94-4e6f8633bbaa")> _

  Public Class StandardAddInServer

    Implements Inventor.ApplicationAddInServer

 

    ‘ Inventor application object.

    Private m_inApp As Inventor.Application

 

    Private myButtonDef As ButtonDefinition

    Private Dim addInCLSIDString As String

 

#Region "ApplicationAddInServer Members"

 

    Public Sub Activate(ByVal addInSiteObject As Inventor.ApplicationAddInSite, ByVal firstTime As Boolean) Implements Inventor.ApplicationAddInServer.Activate

 

      ‘ This method is called by Inventor when it loads the AddIn.

      ‘ The AddInSiteObject provides access to the Inventor Application object.

      ‘ The FirstTime flag indicates if the AddIn is loaded for the first time.

 

      ‘ TODO:  Add ApplicationAddInServer.Activate implementation.

      ‘ e.g. event initialization, command creation etc.

      m_inApp = addInSiteObject.Application

 

      ‘ Retrieve the GUID of this class for later use

 

      Dim addInCLS As GuidAttribute

      addInCLS = CType(System.Attribute.GetCustomAttribute(GetType(StandardAddInServer), _

           GetType(GuidAttribute)), GuidAttribute)

      addInCLSIDString= "{" & addInCLS.Value & "}"

 

      ‘ Create the button definition objects

 

      Dim smallIcon As System.Drawing.Icon

      smallIcon = New System.Drawing.Icon(My.Resources.MyCommand1Icon, 16, 16)

      Dim largeIcon As System.Drawing.Icon

      largeIcon = New System.Drawing.Icon(My.Resources.MyCommand1Icon, 32, 32)

 

      Dim smallPic As IPictureDisp

      smallPic = Microsoft.VisualBasic.Compatibility.VB6.IconToIPicture(smallIcon)

      Dim largePic As IPictureDisp

      largePic = Microsoft.VisualBasic.Compatibility.VB6.IconToIPicture(largeIcon)

 

      myButtonDef = m_inApp.CommandManager.ControlDefinitions.AddButtonDefinition( _

          "Test", "vbButton:Btn1", _

          CommandTypesEnum.kShapeEditCmdType, _

          addInCLSIDString, "test", _

          "", smallPic, largePic)

 

      ‘ Link the button objects with the event

 

      AddHandler myButtonDef.OnExecute, AddressOf MyButtonDefinition_OnExecute

 

    &#160
;
‘ Start UI customization:

 

      If firstTime = True Then

 

        ‘ Access user interface manager

 

        Dim uiManager As UserInterfaceManager

        uiManager = m_inApp.UserInterfaceManager

 

        Dim interfaceStyle As InterfaceStyleEnum

        interfaceStyle = uiManager.InterfaceStyle

 

        If interfaceStyle = InterfaceStyleEnum.kRibbonInterface Then

 

          ‘ Create our commands in ribbon interface

 

          Dim ribbons As Ribbons

          ribbons = uiManager.Ribbons

 

          ‘ Assembly: add our commands in Assembly environment

 

          Dim myRibbon As Ribbon

          myRibbon = ribbons.Item("ZeroDoc")

 

          ‘ Get the tabs associated ribbon

 

          Dim ribbonTabs As RibbonTabs

          ribbonTabs = myRibbon.RibbonTabs

          Dim myTab As RibbonTab

          myTab = ribbonTabs.Add("MyAddIn", "vbButton:ButtonTab1", _

            addInCLSIDString, "")

 

          ‘ Create a new panel within our new tab

 

          Dim ribbonPanels As RibbonPanels

          ribbonPanels = myTab.RibbonPanels

          Dim myPanel As RibbonPanel

          myPanel = ribbonPanels.Add("My Panel", _

          "vbButton:myPanel1", addInCLSIDString, "", False)

 

          ‘ Add two commands to the Clone panel

 

          Dim myPanelCtrls As CommandControls

          myPanelCtrls = myPanel.CommandControls

 

          Dim myCloneBtnCmdCtrl As CommandControl

          myCloneBtnCmdCtrl = myPanelCtrls.AddButton(myButtonDef, True, True, "", False)

        End If

      End If

 

      ‘ End UI customization.

    End Sub

    Private Sub MyButtonDefinition_OnExecute(ByVal Context As Inventor.NameValueMap)

      Dim f As Form1 = New Form1(m_inApp, addInCLSIDString)

      f.ShowDialog()

    End Sub

 

    Public Sub Deactivate() Implements Inventor.ApplicationAddInServer.Deactivate

 

      ‘ This method is called by Inventor when the AddIn is unloaded.

      ‘ The AddIn will be unloaded either manually by the user or

      ‘ when the Inventor session is terminated.

 

      ‘ TODO:  Add ApplicationAddInServer.Deactivate implementation

 

      ‘ Release objects.

      Marshal.ReleaseComObject(m_inApp)

      m_inApp = Nothing

      RemoveHandler myButtonDef.OnExecute, AddressOf MyButtonDefinition_OnExecute

      Marshal.ReleaseComObject(myButtonDef)

      myButtonDef = Nothing

      System.GC.WaitForPendingFinalizers()

      System.GC.Collect()

 

    End Sub

 

    Public ReadOnly Property Automation() As Object Implements Inventor.ApplicationAddInServer.Automation

 

      ‘ This property is provided to allow the AddIn to expose an API

      ‘ of its own to other programs. Typically, this  would be done by

      ‘ implementing the AddIn’s API interface in a class and returning

      ‘ that class object through this property.

 

      Get

        Return Nothing

      End Get

 

    End Property

 

    Public Sub ExecuteCommand(ByVal commandID As Integer) Implements Inventor.ApplicationAddInServer.ExecuteCommand

 

      ‘ Note:this method is now obsolete, you should use the

      ‘ ControlDefinition functionality for implementing commands.

 

    End Sub

 

#End Region

 

  End Class

 

End Namespace

Form1.Designer.vb:

Imports Inventor 

Namespace vbButton

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

    Partial Class Form1

 

        Inhe
rits
System.Windows.Forms.
Form

        Public Sub New(app As Inventor.Application, addInCLS As String)

        MyBase.New

        InitializeComponent

        Dim uiMgr As UserInterfaceManager =app.UserInterfaceManager

        Dim myDockableWindow As DockableWindow = uiMgr.DockableWindows.Add(addInCLS, "MyWindow", "My Add-in Dock")

        myDockableWindow.AddChild(Me.Handle)

        ‘ Default docking state

        If Not myDockableWindow.IsCustomized Then

            myDockableWindow.DockingState = DockingStateEnum.kFloat

            myDockableWindow.Move(25, 25, myDockableWindow.Height, myDockableWindow.Width)

        End If

        Me.Visible = true

        myDockableWindow.Visible = true

    End Sub

        ‘Form overrides dispose to clean up the component list.

        <System.Diagnostics.DebuggerNonUserCode()> _

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)

            Try

                If disposing AndAlso components IsNot Nothing Then

                    components.Dispose()

                End If

            Finally

                MyBase.Dispose(disposing)

            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.ElementHost1 = New System.Windows.Forms.Integration.ElementHost()

            Me.ButtonCtrl1 = New ButtonCtrl()

            Me.SuspendLayout()

           

            ‘ElementHost1

           

            Me.ElementHost1.Dock = System.Windows.Forms.DockStyle.Fill

            Me.ElementHost1.Location = New System.Drawing.Point(0, 0)

            Me.ElementHost1.Name = "ElementHost1"

            Me.ElementHost1.Size = New System.Drawing.Size(284, 262)

            Me.ElementHost1.TabIndex = 0

            Me.ElementHost1.Text = "ElementHost1"

            Me.ElementHost1.Child = Me.ButtonCtrl1

           

            ‘Form1

           

            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)

            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font

            Me.ClientSize = New System.Drawing.Size(284, 262)

            Me.Controls.Add(Me.ElementHost1)

            Me.Name = "Form1"

            Me.Text = "Form1"

            Me.ResumeLayout(False)

 

        End Sub

        Friend WithEvents ElementHost1 As System.Windows.Forms.Integration.ElementHost

        Friend ButtonCtrl1 As Bu
ttonCtrl

    End Class

End Namespace

 

The following picture is the running result: (The sample WPF control is a just button with formatting text and picture tooltip)

Screen shot 2012-06-25 at 4.22.52 PM


Comments

3 responses to “Embedding a WPF User Control in a DockableWindow in Inventor”

  1. Hi, thank you for the awesome code snippet. I have been able to get the above code to work, but when trying to reopen a previously closed dockable window within Inventor 2014, it will not open. Basically, the dockable window will open only once during the application. Is there a way to make it open every time? Thank you!

  2. kent boettger Avatar
    kent boettger

    Hello Jakal,
    open a document and go to view, userinterface. here you can turn it on / of.
    here is a code sample i put together based on a sample in inventor API. put this insite the standardserveraddin.vb
    create a button that calls the code, create a form in your project called form3.
    Public Sub DockableWindow()
    Dim oUserInterfaceMgr As UserInterfaceManager
    oUserInterfaceMgr = m_inventorApplication.UserInterfaceManager
    ‘ Create a new dockable window
    Dim oWindow As Inventor.DockableWindow
    oWindow = oUserInterfaceMgr.DockableWindows.Add(“KBSampleClientId”, “KBTestWindowInternalName”, “KBTest Window”)
    ‘ Get the hwnd of the dialog to be added as a child
    ‘ CHANGE THIS VALUE!
    ‘Dim hwnd As Long
    ‘hwnd = 4851096
    ‘Create the new UserControl
    Dim NewForm3 As New Form3()
    ‘ Add the UserControl as a child to the dockable window
    oWindow.AddChild(NewForm3.Handle)
    ‘ Add the dialog as a child to the dockable window
    ‘Call oWindow.AddChild(hwnd)
    ‘ Don’t allow docking to top and bottom
    oWindow.DisabledDockingStates = Inventor.DockingStateEnum.kDockTop + Inventor.DockingStateEnum.kDockBottom
    ‘ Make the window visible
    oWindow.Visible = True
    End Sub
    regards. kent boettger

  3. Rossano Trindade Avatar
    Rossano Trindade

    Good Morning!
    What would be the reason that text boxes do not work in WPF control? it looks like the command is not executed by the control!
    Has anyone ever had this problem?

Leave a Reply to Rossano TrindadeCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading