My First Plug-in Training

Lesson 4: UI’s and Coding Logic

In previous lessons, you learned how to create a basic Windows Forms application and connect it to a session of Inventor. In this lesson, you will add a button to the form and have it hide selected components, using the code you entered in Lesson 1. You will also spend some time to understand how the code functions.

Provide Feedback: Please provide feedback about this Inventor Training or this lesson via email: myfirstplugin@autodesk.com
Lesson Downloads
lesson4_vb-net.zip (zip - 25Kb)
lesson4_c-sharp.zip (zip - 27Kb)

Coding the New Functionality

We have talked about how a program is a sequence of instructions telling the computer how to do something. Many programs will also need some type of User Interface, for the end user to interact with your new functionality. The Visual Basic Express toolbox makes it very easy to add user interface elements, such as buttons, to enable this interaction.
  1. In the Solution Explorer right click on Form1.vb and select View Designer (or use Shift+F7). 



    The Designer is where you can create the user Interface. In this example you are going to add one button.
  1. From the View menu select Other Windows and then select Toolbox (or use Ctrl+Alt+X).




  2. On the Toolbox, select Button and draw a button on the Form by clicking and dragging to specify the position and size of the button.



  3. You now need to assign a behavior to your button: code that gets executed when someone clicks on it. To do this you need to get to the code window for the form and then get to the code that will run when the button is clicked: Right-click on Form1.vb and select View Code (or use F7), then use the dropdown at the top left of the code window to select Button1.



    In the right dropdown, select the Click event (the icon used for events is a lightning bolt).



    This results in the Sub Button1_Click event hander being added to the code window for the Form and assigned to the button:

    Private Sub Button1_Click(ByVal sender As Object, 
    ByVal e As System.EventArgs) Handles Button1.Click
     
    End Sub

  4. Add the following If statement to Sub Button1_Click:

    If _invApp.Documents.Count = 0 Then
        MsgBox("Need to open an Assembly document")
        Return
    End If

  5. Add the following to Sub Button1_Click (after the “If Then” statement added in step 5):

    If _invApp.ActiveDocument.DocumentType <> _
                  DocumentTypeEnum.kAssemblyDocumentObject Then
           MsgBox("Need to have an Assembly document active")
           Return
    End If

    These two steps make sure a) at least one document is open and b) the active document is an assembly (your code is going to hide assembly components, after all). If a different type of document is active then you ask the user to make an assembly active and then Return from your Sub without executing any more code.

  6. Add the following to Sub Button1_Click after the “If Then” statement in step 6:

     Dim asmDoc As AssemblyDocument
     asmDoc = _invApp.ActiveDocument
     
    If asmDoc.SelectSet.Count = 0 Then
         MsgBox("Need to select a Part or Sub Assembly")
         Return
    End If

  7. Add the following to Sub Button1_Click after the “If Then” statement in step 7:

    Dim selSet As SelectSet
    selSet = asmDoc.SelectSet
     
    Try
         Dim compOcc As ComponentOccurrence
         Dim obj As Object
     
         For Each obj In selSet
              compOcc = obj
              Debug.Print(compOcc.Name)
              compOcc.Visible = False
         Next
    Catch ex As Exception
         MsgBox("Is the selected item a Component?")
         MsgBox(ex.ToString())
         Return
    End Try

    This completes the code for this lesson. The code now checks to see if an assembly is active and some entities are selected. It then prints out the name of the component (an occurrence) and makes it invisible. If the selected entity is not a component then an error will occur and the catch block will handle it.

Running the Plug-in

  1. Start Autodesk Inventor. (Note: When the plug-in is run it will start a new session of Inventor if one is not already open.)

  2. Create or open an existing Inventor assembly:
     Either unzip the Clutch_Bell_Simplified.zip file, and open the Clutch_Bell_Simplified.iam assembly or within Inventor make sure you have activated an assembly of your choice.  There are several types of document that can be created or worked with inside Inventor. The most commonly used document types are Part (.ipt), Assembly (.iam) and Drawing (.idw). Open a new assembly and place some parts using the standard Inventor user interface.

  3. Run your plug-in with Inventor and allow the plug-in to communicate with Inventor:
    To make Visual Basic Express execute the code you have entered, select Start Debugging on the Debug menu (you can use the F5 key or click on the green arrow – which looks like a “play” button – on the Debugging toolbar). This will cause your form to be displayed. You may need to minimize VB Express to see both the form and Inventor.

  4. Switch to the Inventor session and select some components in an assembly, which will take the focus away from your application’s form. Bring the application back in front of the Inventor session and click the button to run your code. The selected components in Inventor should now be hidden and – in the browser – display for the components should now be unchecked.

A Closer Look at the Code

In previous lessons, you learned that a class can have functions/subs and properties. Classes also generate events when things happen for your code to respond to: you want to respond to your button’s click event, for instance, and it’s in your handler for this event (which is a special kind of function) that you’ve added the rest of the code in this lesson.

Private Sub Button1_Click(ByVal sender As Object, 
ByVal e As System.EventArgs) Handles Button1.Click End Sub

When the button is clicked you want to get the components in the assembly that the user has already selected. To do this you need to use the SelectSet property of the document.

To make sure the rest of your code can function, you first need to check Inventor has a document open. You do this by checking the number of items in the Documents collection from the Inventor Application object via the collection’s Count property. Notice how you’re using the dot notation to “walk the hierarchy”, going from one object to another via properties.

If _invApp.Documents.Count = 0 Then
       MsgBox("Need to open an Assembly document")
       Return
End If

An “If Then” statement lets you execute code conditionally: if the condition between the “If” and the “Then” evaluates to true, then the code between the “Then” and the “End If” gets executed. In this example, when the Count property is zero, you know that no documents are open in Inventor. At this point you tell the user to open an assembly and you then Return from the Sub – jumping to the end of the Sub without executing any further code. It’s much better to check for problematic situations in this way than to let the code fail and generate a confusing error message. The Return keyword does not cause your application to exit completely – it only Returns from the Sub – so the user can simply open an assembly and click the button again.

The next piece of code is another “If Then” statement: this time to make sure the document that’s active in Inventor is an assembly, as your code only works with assembly components. In this case you use a slightly different comparison: you use the inequality operator (<>) rather than the equality operator (=). So if the active document is not an assembly you present a different message to the user and Return from the Sub.

If _invApp.ActiveDocument.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then
       MsgBox("Need to have an Assembly document active")
       Return
If your code gets past these two “If Then” statements then you know an assembly is active and you can proceed to get the SelectSet from it.

 Dim asmDoc As AssemblyDocument
 asmDoc = _invApp.ActiveDocument
 
If asmDoc.SelectSet.Count = 0 Then
     MsgBox("Need to select a Part or Sub Assembly")
     Return
End If

You use the Dim statement to declare a variable named “asmDoc” of type “AssemblyDocument” and directly assign the contents of the Inventor Application’s ActiveDocument property to it using the equals sign (which is also the assignment operator in VB.NET). If you make changes to asmDoc using one of its properties, the change will take effect on the active document. Here you are just using one of the properties, “SelectSet”, in an “If Then” statement – you’re not modifying the document at all. Once again you’re checking the Count property, to see whether the SelectSet contains any items: if the user did not select anything then you ask them to do so before Returning from the Sub.

At this point in your code, you know that something is selected in the active Inventor assembly. Now you will go ahead and do something to each of the selected components.

Dim selSet As SelectSet
selSet = asmDoc.SelectSet
 
Try
     Dim compOcc As ComponentOccurrence
     Dim obj As Object
 
     For Each obj In selSet
          compOcc = obj
          Debug.Print(compOcc.Name)
          compOcc.Visible = False
     Next
Catch ex As Exception
     MsgBox("Is the selected item a Component?")
     MsgBox(ex.ToString())
     Return
End Try

Here you assign the SelectSet containing the selected entities from the active AssemblyDocument to the “selSet” variable. A Try Catch block is used for error checking: if a problem occurs while executing the code inside the Try block, the code in the Catch block gets executed, allowing you to provide further information to the user about the problem (in this case you ask them to make sure they have selected one or more components).

Within the Try block, you use a “For Next” loop to step through each of the entities in the SelectSet. If only one entity is selected then the code between the “For Each” and “Next” statements will only be processed once. If there are more entities selected, the code will be processed once for each entity. You know that the code will be executed at least once, as you would already have returned from the Sub if there were no entities in the SelectSet. The SelectSet could contain any type of entity that is selectable in Inventor: it’s for this reason you access its contents using the generic “Object” type (a type that can contain any kind of object). If the user has selected something other than a Component, an error will be generated when you attempt to assign it to your “compOcc” variable of type ComponentOccurrence. Assuming this assignment doesn’t cause an error, the next line will execute which uses Debug.Print to send the name of the ComponentOccurrence to the Immediate window in Visual Basic Express. This window can be displayed in Visual Basic Express from the Debug menu > Windows (or Ctrl+G). Using Debug.Print and the immediate window is a useful tool if a problem occurs and you need to work out what is wrong. Notice that the Immediate window is accessed from a different location then the Error List which is accessed from View > Other Windows. After the Debug.Print statement, you reach the goal of this lesson’s code: to hide the selected components by setting their Visible property to False.

Well done! You have just written a more robust plug-in by hiding the selected components programmaticallyand anticipating the possibility of something unexpected happening with the use of your plug-in, which will, in turn, improve the user experience.