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.