This is a follow-up on my tutorials on creating an addin. In the 1e part, we created an addin that searches all iLogic rules. We used an inputbox to get input from the user. We used notepad to show the results to the user. We can do this in a more elegant way by creating a custom form (window). 

You can make forms as simple or difficult as you like. In this tutorial, I will keep it as simple as possible. The main point of this tutorial will be to learn how you can use a form. Therefore We will create a very simple form. I just want you to learn the basics. But when you start creating forms you probably still need to google yourself.

We start with creating the form layout. Add a form to your application and call it “MySearchForm”.

Open the form and the toolbox panel. 

Now you can place 2 TextBox controls and button control. Placing a control can be done by:

  • Select a control from the toolbox (for example the Button control)
  • Click in the window and drag the mouse

Each control also has some properties.

You should definitely play around with them. You can do nice things with those properties but not important for this tutorial. For now, you need to set the “Name” property of each control. I called my controls: “TbSearchText”, “TbResults” and “BtnSearch” (Tb for TextBox and Btn for Buton)

All controls also have some events. For example, the button command has an event called “Click”. As you might have guessed this event is fired when the button is clicked. We can catch the event by doing the following: Have a look at the property window and find the “Event handlers” button. Then enter “BtnSearch_Click” in the “Click” textbox.

You might have seen that you can also alter the design by XAML code. This is what my XAML code looks like:

<Window x:Class="MySearchForm"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyILogicAddin"
        mc:Ignorable="d"
        Title="MySearchForm" Height="309" Width="380">
    <Grid>
        <TextBox x:Name="TbSearchText" Height="22" Margin="10,10,114,0" TextWrapping="Wrap" VerticalAlignment="Top"/>
        <Button x:Name="BtnSearch" Click="BtnSearch_Click" Con-tent="Search" HorizontalAlignment="Right" Height="22" Margin="0,10,10,0" VerticalAlignment="Top" Width="99"/>
        <TextBox x:Name="TbResults" Margin="10,37,10,10" TextWrap-ping="NoWrap" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVis-ibility="Visible"/>
    </Grid>
</Window>

In your “Solution explorer” have a close look at the file you just created. You will see that there are actually 2 files. 

In my case “MySearchForm.xaml” and “MySearchForm.xaml.vb”. The first holds the designer info and is the file we just altered. The 2e holds the logic. Change the default code to the following. 

Imports System.Text
Imports Inventor

Public Class MySearchForm

    Private ReadOnly iLogicAddinGuid As String = "{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}"
    Private ReadOnly _iLogicAutomation
    Private ReadOnly _nl As String
    Private ReadOnly _inventor As Inventor.Application

    Public Sub New(inventor As Inventor.Application)

        ' This call is required by the designer.
        InitializeComponent()

        _inventor = inventor
        Dim iLogicAddin As ApplicationAddIn = _inventor.ApplicationAddIns.ItemById(iLogicAddinGuid)
        _iLogicAutomation = iLogicAddin.Automation

        _nl = System.Environment.NewLine

    End Sub

    Private Sub BtnSearch_Click(sender As Object, e As RoutedEventArgs)
        Dim _document As Document = _inventor.ActiveDocument
        Dim stringBuilder As New StringBuilder()

        SearchDoc(_Document, stringBuilder)
        For Each refDoc As Document In _Document.AllReferencedDocuments
            SearchDoc(refDoc, stringBuilder)
        Next

        TbResults.Text = stringBuilder.ToString()
    End Sub


    Private Sub SearchDoc(doc As Document, stringBuilder As StringBuilder)
        Dim searchText = TbSearchText.Text
        Dim rules = _iLogicAutomation.Rules(doc)
        If (rules Is Nothing) Then Return
        For Each rule In rules
            Dim strReader As New IO.StringReader(rule.Text)
            Dim i As Integer = 1

            Do While (True)
                Dim line As String
                line = strReader.ReadLine()
                If line Is Nothing Then Exit Do
                If (line.ToUpper().Contains(searchText.ToUpper())) Then

                    stringBuilder.Append($"Doc name : {doc.DisplayName}{_nl}")
                    stringBuilder.Append($"Rule name: {rule.Name}{_nl}")
                    stringBuilder.Append($"Line {i}: {line.Trim()}{_nl}")
                    stringBuilder.Append(_nl)

                End If
                i += 1
            Loop
        Next
    End Sub

End Class 

You should notice some things here:

  • The constructor (Sub New) takes the inventor object as a parameter. This will enable us to use inventor api in the form.
  • In this class you also find the code for the method “BtnSearch_Click” that we created earlier.
  • The method SearchDoc(....) represents the same code we did have in the old code.

Now we have the forum we need to start using it. In the MyButton.MyButton_OnExecute(...) method we are using the class ThisRule. That has to go and we should start the new form from there. The new method needs to look like this:

Private Sub MyButton_OnExecute(Context As NameValueMap)
    Try
        Dim mySearchForm As New MySearchForm(_inventor)
        mySearchForm.ShowDialog()
    Catch ex As Exception
        MsgBox("Something went wrong while runing rule. Message: " & ex.Message)
    End Try
End Sub

  If you now start the addin, everything will work but we have some refactoring to do.

  • The classes "AbstractRule" and "ThisRule" are not used anymore. Therefore they can be deleted.
  • "Module1" in the project "MyDebugApp" is also using the old rule class. That has to change to:
Imports Inventor
Imports System.Runtime.InteropServices
Imports MyILogicAddin ' This is the namespace from the addin dll!

Module Module1
    Sub Main()
        Dim inventorObject As Inventor.Application = Marshal.GetActiveObject("Inventor.Application")

        Dim mySearchForm As New MySearchForm(inventorObject)
        mySearchForm.ShowDialog()
    End Sub
End Module

Edit

2022-12-28: Changed the class "MySearchForm". When the search button is clicked the active document is used instead of the active document when the class was initialized.

Skills:

Autodesk Inventor, Vault, Git, C#, vb, .net, php HTML, css, js

Education:

University computer science.
HBO Mechanical engineer.
MBO Fine mechanics.

Experience:

Programmer and Mechanical engineer at Kelvion
(2016 - 20..)

Mechanical engineer at Strukton
(2009 - 2016)

Mechanical engineer at RDG-engineering
(2007 - 2009)

CNC Programmer at VMC
(2005 - 2007)

volunteer at Taizé
(2007)

Certifications:

Objectgeoriënteerd analyseren en ontwerpen, Objectgeoriënteerd programmeren in Java, Webapplicaties: de clientkant, Databases, Security Aware Programmer, Web Security Specialist