Erstellen eines flexiblen Auswahldialogs mit WindowsForms und ListBox in Inventor-Regeln
Ein Auswahldialog, der automatisch die Namen der meisten Inventor-API Objekte anzeigt, das gewählte Objekt und DialogResult zurückgibt und anpassbar ist
Links zum Thema:
Das Video zum flexiblen Inventor-API Auswahldialog bei Youtube oder DailyMotion .
Warum ein selbst gebauter Auswahldialog?
Die Inventor-API bietet, um Benutzer aus einer Liste etwas wählen zu lassen, nur die iLogic InputListBox bzw. den InputListBoxDialog. Diese verlangen als Eingabe eine Liste von Strings oder Objekten, deren .ToString Methode verwendet wird, um die angezeigte Liste zu füllen. Die meisten Inventor-Objekte liefern mit .ToString aber nur ihre Typbezeichnung "System.__Com-Object" zurück. Um das zu kompensieren, kenne ich bisher nur den workaround, der von Jelte de Jong vorgeschlagen wurde und für viele Fälle ausreicht: Zuerst werden alle Objekte der Liste in neue Objekte einer Wrapperklasse mit angepasster .ToString Methode verpackt, und dann der InputListBox eine Liste mit Wrapperopjekten übergeben, was manchmal etwas umständlich erscheint.
Außerdem ist dann auch der Rückgabewert der InputListBox ein Wrapperobjekt und nicht das Objekt, mit dem weiter gearbeitet wird.
Zwar kann man, wenn man einen InputListBoxDialog deklariert und ShowDialog aufruft, ein DialogResult erhalten und auf einige Eigenschaften wie z. B. das gewählte Objekt und den gewählten Index zugreifen nach Schließen des Dialogs. Allerdings erhält man auch hier anscheinend keine Möglichkeit, den angezeigten Inhalt der Liste zu beeinflussen, da diese erst nach dem Aufruf von ShowDialog gefüllt wird. Man kann die angezeigten Strings also nicht gegen die tatsächlichen Objektnamen tauschen.
Deshalb habe ich eine eigene AuswahlDialog Klasse geschrieben, die aus einer Objektliste die üblichen Namenseigenschaften ausliest und anzeigt, das gewählte Objekt zurückgibt und auch den DialogResult. Da der Dialog wie üblich bei WindowsForms vor dem Anzeigen als Objekt angelegt wird, können alle Eigenschaften des Dialogs angepasst werden.
Hier erkläre ich den Code zuerst Abschnittsweise, am Ende folgt der komplette Code.
Main-Methode und Verwendung des Dialogs
Zuerst die Einleitung: Wir importieren die Fensterverwaltung für Windows-apps und Reflection, um Typeigenschaften abfragen zu können. Dann kommt die main-Methode. Das sind die Voraussetzungen für die Verwendung der AuswahlDialog Klasse.
Damit wir den Dialog mittig auf dem Inventor-Hauptfenster platzieren können, brauchen wir dessen Geometrie.
Imports System.Windows.Forms
Imports System.Reflection
Sub Main()
Dim invApp As Inventor.Application = ThisApplication
Dim width As Integer = invApp.Width
Dim height As Integer = invApp.Height
Dim links As Integer = invApp.Left
Dim oben As Integer = invApp.Top
Dim fenstermitte As Point2d = invApp.TransientGeometry.CreatePoint2d(links + width \ 2, oben + height \ 2)
Als nächstes wird das parametrisch typisierte Dialogfenster erzeugt. Was dabei genau passiert kommt bei der Erklärung der Klasse. In diesem Fall soll eine Liste von Werkstoffen ausgegeben werden, die in einer als Beispiel willkürlich gewählten Werkstoffbibliothek enthalten sind. Die Dialogfenstergröße wird mit der Anpassungsmethode an die Anzahl der Werkstoffe angepasst. Die Höhe ist die Höhe des Inventorfensters, weil es mir aus Inventor heraus nicht gelungen ist, die Bildschirmhöhe zu lesen. Ähnliches gilt für die Position, die auf die Mitte des Inventor-Fensters gesetzt wird. Eine Schaltfläche wird umbenannt.
Dim werkstoffauswahlDialog As New AuswahlDialog(Of Asset)(invApp.AssetLibraries(2).MaterialAssets)
werkstoffauswahlDialog.Text = "Werkstoff auswählen"
werkstoffauswahlDialog.ButtonOK.Text = "Auswählen"
werkstoffauswahlDialog.AdjustWindowHeight(height)
werkstoffauswahlDialog.SetPos(fenstermitte.X - werkstoffauswahlDialog.Width \ 2, fenstermitte.Y - werkstoffauswahlDialog.Height \ 2)
Der nächste Abschnitt zeigt den erstellten Dialog modal an, wartet auf Eingabe und verarbeitet die Benutzerauswahl. Wenn der Benutzer "OK" wählt, wird das ausgewählte Asset in der Variablen werkstoff gespeichert. Wenn ein Werkstoff ausgewählt wurde, wird dessen Name ausgegeben; hier würde normalerweise natürlich irgendetwas mit dem gewählten Werkstoff passieren. Bei Abbruch wird eine Meldung protokolliert und die Subroutine beendet. Das könnte man auch schon vorher machen, wenn man auf DialogResult.Cancel prüft.
Dim werkstoff As Asset = Nothing
Dim antwort As DialogResult = werkstoffauswahlDialog.ShowDialog()
If antwort = DialogResult.OK Then
werkstoff = werkstoffauswahlDialog.SelectedItem
End If
If werkstoff IsNot Nothing Then
Logger.Info(werkstoff.DisplayName & " ausgewählt.")
Else
Logger.Info("Kein Werkstoff ausgewählt.")
Exit Sub
End If
End Sub
Aufbau des Dialogs
Der nächste Codeabschnitt definiert den Kern des Themas: Die Klasse AuswahlDialog, die von Form (einem Windows-Fenster) erbt und überwiegend automatisch von Visual Studio generiert wurde. Außerdem wird ein generischer Typ T verwendet. Der Typ ermöglicht es uns, genau so ein Objekt zurückzugeben, wie wir in der Liste erhalten haben. Die Steuerelemente ListBox1, ButtonOK und ButtonCancel sowie Eigenschaften für den ausgewählten Index (SelectedIndex), das ausgewählte Element (SelectedItem), einen Adapter (Adapter; dazu später mehr) und die anzuzeigenden Elemente (Items). Das SelectedItem soll den parametrischen Typ annehmen. Der Konstruktor der Klasse initialisiert den Dialog, indem er die Anzahl der Elemente in der übergebenen IEnumerable ermittelt. Dabei werden verschiedene Möglichkeiten zur Bestimmung der Anzahl ausprobiert (Length-Property, Count-Property, Count-Methode oder durch Iteration), weil es in Inventor verschiedene Typen von Objektsammlungen geben kann. Wenn gar kein direkter Weg zum Ermitteln der Anzahl gefunden wird, zählen wir einfach durch.
Public Class AuswahlDialog(Of T)
Inherits Form
Private ReadOnly ListBox1 As New ListBox()
Friend ButtonOK As New Button()
Friend ButtonCancel As New Button()
Public Property SelectedIndex As Integer
Public Property SelectedItem As T
Private Property Adapter As IObjektAdapter
Private Property Items As IEnumerable
Public Sub New(items As IEnumerable, Optional adapter As IObjektAdapter = Nothing, Optional startIndex As Integer = -1)
Dim anzahl As Integer = 0
Dim listTypeInfo As Type = items.GetType()
Dim prop As System.Reflection.PropertyInfo
prop = listTypeInfo.GetProperty("Length")
If prop Is Nothing Then
prop = listTypeInfo.GetProperty("Count")
End If
If prop IsNot Nothing Then
anzahl = prop.GetValue(items)
Else
Dim met As System.Reflection.MethodInfo
met = listTypeInfo.GetMethod("Count")
If met IsNot Nothing Then
anzahl = listTypeInfo.GetMethod("Count").Invoke(items, Nothing)
anzahl = met.Invoke(items, Nothing)
Else
For Each item As Object In items
anzahl += 1
Next
End If
End If
Bestimmen der Auswertungsart zur Erzeugung der Listenanzeige
Dieser Abschnitt bestimmt, wie die Elemente in der ListBox angezeigt werden sollen. Wenn kein Adapter übergeben wurde, versucht der Code, die anzuzeigenden Werte automatisch zu ermitteln. Dazu prüft er, ob die Elemente eine DisplayName-Property, eine Name-Property oder eine ToString-Methode haben. Wenn ein Adapter vorhanden ist, der die Methode zur Erzeugung der Stringliste enthält, wird dieser für die Anzeige verwendet. Der Code greift zur Laufzeit dynamisch auf die Eigenschaften der Objekte zu und behandelt Exceptions, falls die erwarteten Properties nicht vorhanden sind. Welche Möglichkeit zur Anzeige gewählt wurde, wird in der Enum auswertung festgelegt.
Dim auswertung As Auswertungsart = Auswertungsart.AuswertungNichts
Me.Items = items
If adapter Is Nothing Then
Dim typeInfo As Type = Nothing
If typeInfo Is Nothing Then
typeInfo = GetType(T)
End If
If typeInfo Is GetType(String) Then
auswertung = Auswertungsart.AuswertungString
ElseIf typeInfo.GetProperty("DisplayName") IsNot Nothing Or typeInfo.GetMethod("DisplayName") IsNot Nothing Then
auswertung = Auswertungsart.AuswertungDisplayName
ElseIf typeInfo.GetProperty("Name") IsNot Nothing Then
auswertung = Auswertungsart.AuswertungName
ElseIf typeInfo.GetMethod("ToString") IsNot Nothing Then
auswertung = Auswertungsart.AuswertungToString
End If
If auswertung = Auswertungsart.AuswertungNichts Then
Dim test As String
Try
test = Me.Items(0).DisplayName
auswertung = Auswertungsart.AuswertungDisplayName
Catch
Try
test = Me.Items(0).Name
auswertung = Auswertungsart.AuswertungName
Catch
End Try
End Try
End If
Else
Me.Adapter = adapter
End If
Konfiguration des Dialogs und Füllen der Listbox
Neben einigen Eigenschaften des Dialogs wird hier die ListBox konfiguriert und das Fenster zusammengebaut. Viel davon ist automatisch generiert, nur der Inhalt der Listbox ist manuell geschrieben. Die Elemente werden in die Liste eingetragen, wobei die vorher ermittelte Auswertungsart berücksichtigt wird. Falls ein Adapter übergeben wurde, wird die Stringliste von dem bezogen. Die Auswahl wird auf den übergebenen Startindex gesetzt, falls dieser gültig ist. Die Schaltflächen werden konfiguriert und die Größe des Dialogs wird angepasst.
Me.Text = "Auswahl treffen"
Me.Width = 320
Me.Height = 300
Me.StartPosition = FormStartPosition.CenterScreen
If Me.Adapter IsNot Nothing Then
ListBox1.Items.AddRange(Me.Adapter.GetStringArray(Me.Items, anzahl))
Else
For i As Integer = 0 To anzahl - 1
Select Case auswertung
Case Auswertungsart.AuswertungString
ListBox1.Items.Add(CType(items(i), String))
Case Auswertungsart.AuswertungDisplayName
ListBox1.Items.Add(items(i).DisplayName)
Case Auswertungsart.AuswertungName
ListBox1.Items.Add(items(i).Name)
Case Auswertungsart.AuswertungToString
ListBox1.Items.Add(items(i).ToString())
Case Else
ListBox1.Items.Add("keine passende Auswertungsart gefunden")
End Select
Next
End If
ListBox1.Dock = DockStyle.Top
AddHandler ListBox1.SelectedIndexChanged, AddressOf ListBox_SelectedIndexChanged
Me.Controls.Add(ListBox1)
Dim panel As New FlowLayoutPanel()
panel.FlowDirection = FlowDirection.RightToLeft
panel.Dock = DockStyle.Bottom
panel.Height = 40
ButtonOK.Text = "OK"
ButtonOK.Enabled = False
AddHandler ButtonOK.Click, AddressOf ButtonOK_Click
panel.Controls.Add(ButtonOK)
If startIndex < anzahl - 1 Then
Me.SelectedIndex = startIndex
Else
Me.SelectedIndex = -1
End If
If Me.SelectedIndex > -1 Then
ListBox1.SelectedIndex = startIndex
Me.SelectedItem = CType(Me.Items(startIndex),T)
End If
ButtonCancel.Text = "Abbrechen"
AddHandler ButtonCancel.Click, AddressOf ButtonCancel_Click
panel.Controls.Add(ButtonCancel)
Me.Controls.Add(panel)
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.AutoSize = True
Me.AdjustWindowHeight()
End Sub
Methoden zum Anpassen von Position und Größe
Die beiden Methoden SetPos und AdjustWindowHeight dienen dazu, den Dialog an die gewünschte Position zu setzen und die Höhe des Dialogs anzupassen. Die Position wird relativ zum Inventor-Fenster gesetzt, die Höhe wird so angepasst, dass die Liste nicht zu lang wird und die Schaltflächen nicht zu weit unten stehen. Die Höhe des Dialogs wird auf die Höhe der Schaltflächen, der Liste und einiger Abstände gesetzt. Hier war einiges an Gebastel nötig, weil einige oft benutzten Methoden und Properties (z. B. ClientSize) für das Fensterlayout Klassen aus System.Drawing.Primitives verwenden, die in Inventor anscheinend nicht verfügbar sind. Da es mir nicht gelungen ist, die benötigten Klassen zu importieren, habe ich die Methoden so umgeschrieben, dass sie ohne diese Klassen auskommen. Falls jemand mir sagen kann, wie ich diese Klassen (z. B. Rectangle oder Pointverwenden kann, bitte ich um Hinweis.
Update: Zwischenzeitlich habe ich herausgefunden, dass die in Inventor blockierten Klassen verwendet werden können, wenn der Auswahldialog als externe DLL kompiliert und in iLogic geladen wird. Das ermöglicht, die Größenanpassungsfunktion einfach so zu verwenden, wie sie von Visual Studio generiert wird.
Public Sub SetPos(links As Integer, oben As Integer)
Me.StartPosition = FormStartPosition.Manual
Me.Left = links
Me.Top = oben
End Sub
Public Sub AdjustWindowHeight(Optional maxHoehe As Integer = 1000)
Dim screenHeight As Integer = maxHoehe
Dim maxlistBoxHeight As Integer = screenHeight \ 2
Dim listBoxHeight As Integer = Math.Min(ListBox1.ItemHeight * ListBox1.Items.Count + 30, maxlistBoxHeight)
ListBox1.Height = listBoxHeight
Dim buttonSpacing As Integer = 10
Me.Height = ButtonOK.Height + 2 * buttonSpacing + ListBox1.Height + 50
End Sub
Eventhandler für die Listbox und die Schaltflächen
Die Eventhandler legen fest, was bei Benutzerinteraktion passieren soll. Wenn ein Element in der Liste ausgewählt wird, wird der Index und das Element gespeichert und die OK-Schaltfläche aktiviert. Wenn die OK-Schaltfläche gedrückt wird, wird der Dialog geschlossen und DialogResult auf OK gesetzt. Wenn die Abbruch-Schaltfläche gedrückt wird, wird DialogResult auf Cancel gesetzt und der Dialog geschlossen.
Außerdem wird eine Enumeration Auswertungsart definiert, die es ermöglicht, die Auswertungsart einfach festzulegen. Danach endet die Klasse.
Private Sub ListBox_SelectedIndexChanged(sender As Object, e As EventArgs)
SelectedIndex = ListBox1.SelectedIndex
SelectedItem = CType(Items(SelectedIndex),T)
ButtonOK.Enabled = (SelectedIndex >= 0)
End Sub
Private Sub ButtonOK_Click(sender As Object, e As EventArgs)
Me.DialogResult = DialogResult.OK
Me.Close()
End Sub
Private Sub ButtonCancel_Click(sender As Object, e As EventArgs)
Me.DialogResult = DialogResult.Cancel
Me.SelectedIndex = -1
Me.Close()
End Sub
Private Enum Auswertungsart
AuswertungNichts
AuswertungString
AuswertungToString
AuswertungDisplayName
AuswertungName
End Enum
End Class
Der Adapter
Für den Fall, dass die Objekte in der Liste nicht die gewünschten Eigenschaften haben, kann ein Adapter übergeben werden, der die gewünschten Eigenschaften ausliest. Der Adapter muss das Interface IObjektAdapter implementieren und die Methode GetStringArray enthalten, die die Objekte in der Liste und die Anzahl der Elemente übergeben bekommt und ein String-Array zurückgibt. Hier ein einfaches Beispiel für einen Adapter, der aus einem Asset die DisplayName-Eigenschaft ausliest, so wie das auch die AuswahlDialog-Klasse selbst macht. Hier kann man für jede Objektart einen eigenen Adapter schreiben, der die gewünschten Eigenschaften ausliest, falls man für einen Einzelfall nicht den AuswahlDialeg ändern möchte.
Public Interface IObjektAdapter
Function GetStringArray(items As IEnumerable, anzahl As Integer) As String()
End Interface
Class AssetAdapter
Implements IObjektAdapter
Public Function GetStringArray(items As IEnumerable, anzahl As Integer) As String() Implements IObjektAdapter.GetStringArray
Dim namen(anzahl - 1) As String
For i As Integer = 0 To anzahl - 1
namen(i) = CType(items(i), Asset).DisplayName
Next
Return namen
End Function
End Class
Der vollständige Code
Um den AuswahlDialog zu verwenden, muss man die Imports, die AuswahlDialog-Klasse und, falls man den Adapter verwenden möchte, auch das IObjektAdapter-Interface und die passend erzeugte Adapterklasse in die iLogic-Regel kopieren. Wenn der Adapter gar nicht benötigt wird, können das Argument im Konstruktor und die Codezeilen, die den Adapter verwenden, entfernt werden.
Hier ist der vollständige Code, der die Auswahl eines Werkstoffs aus der zweiten Werkstoffbibliothek ermöglicht.
Imports System.Windows.Forms
Imports System.Reflection
Sub Main()
Dim invApp As Inventor.Application = ThisApplication
Dim width As Integer = invApp.Width
Dim height As Integer = invApp.Height
Dim links As Integer = invApp.Left
Dim oben As Integer = invApp.Top
Dim fenstermitte As Point2d = invApp.TransientGeometry.CreatePoint2d(links + width \ 2, oben + height \ 2)
Dim werkstoffauswahlDialog As New AuswahlDialog(Of Asset)(invApp.AssetLibraries(2).MaterialAssets)
werkstoffauswahlDialog.Text = "Werkstoff auswählen"
werkstoffauswahlDialog.ButtonOK.Text = "Auswählen"
werkstoffauswahlDialog.AdjustWindowHeight(height)
werkstoffauswahlDialog.SetPos(fenstermitte.X - werkstoffauswahlDialog.Width \ 2, fenstermitte.Y - werkstoffauswahlDialog.Height \ 2)
Dim werkstoff As Asset = Nothing
Dim antwort As DialogResult = werkstoffauswahlDialog.ShowDialog()
If antwort = DialogResult.OK Then
werkstoff = werkstoffauswahlDialog.SelectedItem
End If
If werkstoff IsNot Nothing Then
Logger.Info(werkstoff.DisplayName & " ausgewählt.")
Else
Logger.Info("Kein Werkstoff ausgewählt.")
Exit Sub
End If
End Sub
Public Class AuswahlDialog(Of T)
Inherits Form
Private ReadOnly ListBox1 As New ListBox()
Friend ButtonOK As New Button()
Friend ButtonCancel As New Button()
Public Property SelectedIndex As Integer
Public Property SelectedItem As T
Private Property Adapter As IObjektAdapter
Private Property Items As IEnumerable
Public Sub New(items As IEnumerable, Optional adapter As IObjektAdapter = Nothing, Optional startIndex As Integer = -1)
Dim anzahl As Integer = 0
Dim listTypeInfo As Type = items.GetType()
Dim prop As System.Reflection.PropertyInfo
prop = listTypeInfo.GetProperty("Length")
If prop Is Nothing Then
prop = listTypeInfo.GetProperty("Count")
End If
If prop IsNot Nothing Then
anzahl = prop.GetValue(items)
Else
Dim met As System.Reflection.MethodInfo
met = listTypeInfo.GetMethod("Count")
If met IsNot Nothing Then
anzahl = listTypeInfo.GetMethod("Count").Invoke(items, Nothing)
anzahl = met.Invoke(items, Nothing)
Else
'Wenn nichts funktioniert, einfach durchzählen
For Each item As Object In items
anzahl += 1
Next
End If
End If
Dim auswertung As Auswertungsart = Auswertungsart.AuswertungNichts
Me.Items = items
'Wenn adapter Nothing ist, wird die Standardauswertung versucht
If adapter Is Nothing Then
Dim typeInfo As Type = Nothing
If typeInfo Is Nothing Then
typeInfo = GetType(T)
End If
If typeInfo Is GetType(String) Then
auswertung = Auswertungsart.AuswertungString
ElseIf typeInfo.GetProperty("DisplayName") IsNot Nothing Or typeInfo.GetMethod("DisplayName") IsNot Nothing Then
auswertung = Auswertungsart.AuswertungDisplayName
ElseIf typeInfo.GetProperty("Name") IsNot Nothing Then
auswertung = Auswertungsart.AuswertungName
ElseIf typeInfo.GetMethod("ToString") IsNot Nothing Then
auswertung = Auswertungsart.AuswertungToString
End If
' versuche, die Auswertung durch Ausprobieren zu finden
If auswertung = Auswertungsart.AuswertungNichts Then
Dim test As String
Try
test = Me.Items(0).DisplayName
auswertung = Auswertungsart.AuswertungDisplayName
Catch
Try
test = Me.Items(0).Name
auswertung = Auswertungsart.AuswertungName
Catch
End Try
End Try
End If
Else
Me.Adapter = adapter
End If
' Form-Einstellungen
Me.Text = "Auswahl treffen"
Me.Width = 320
Me.Height = 300
Me.StartPosition = FormStartPosition.CenterScreen
' ListBox hinzufügen
' Wenn wir einen adapter haben, verwenden wir diesen
If Me.Adapter IsNot Nothing Then
ListBox1.Items.AddRange(Me.Adapter.GetStringArray(Me.Items, anzahl))
Else
For i As Integer = 0 To anzahl - 1
Select Case auswertung
Case Auswertungsart.AuswertungString
ListBox1.Items.Add(CType(items(i), String))
Case Auswertungsart.AuswertungDisplayName
ListBox1.Items.Add(items(i).DisplayName)
Case Auswertungsart.AuswertungName
ListBox1.Items.Add(items(i).Name)
Case Auswertungsart.AuswertungToString
ListBox1.Items.Add(items(i).ToString())
Case Else
ListBox1.Items.Add("keine passende Auswertungsart gefunden")
End Select
Next
End If
ListBox1.Dock = DockStyle.Top
AddHandler ListBox1.SelectedIndexChanged, AddressOf ListBox_SelectedIndexChanged
Me.Controls.Add(ListBox1)
' Panel für Buttons
Dim panel As New FlowLayoutPanel()
panel.FlowDirection = FlowDirection.RightToLeft
panel.Dock = DockStyle.Bottom
panel.Height = 40
' OK-Button
ButtonOK.Text = "OK"
ButtonOK.Enabled = False
AddHandler ButtonOK.Click, AddressOf ButtonOK_Click
panel.Controls.Add(ButtonOK)
If startIndex < anzahl - 1 Then
Me.SelectedIndex = startIndex
Else
Me.SelectedIndex = -1
End If
If Me.SelectedIndex > -1 Then
ListBox1.SelectedIndex = startIndex
Me.SelectedItem = CType(Me.Items(startIndex),T)
End If
' Cancel-Button
ButtonCancel.Text = "Abbrechen"
AddHandler ButtonCancel.Click, AddressOf ButtonCancel_Click
panel.Controls.Add(ButtonCancel)
Me.Controls.Add(panel)
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.AutoSize = True
Me.AdjustWindowHeight()
End Sub
Public Sub SetPos(links As Integer, oben As Integer)
Me.StartPosition = FormStartPosition.Manual
Me.Left = links
Me.Top = oben
End Sub
Public Sub AdjustWindowHeight(Optional maxHoehe As Integer = 1000)
' Bildschirmhöhe übernehmen
Dim screenHeight As Integer = maxHoehe
' Maximale Höhe der listBox (halbe Bildschirmhöhe)
Dim maxlistBoxHeight As Integer = screenHeight \ 2
' Berechnung der listBox-Höhe basierend auf den Einträgen
Dim listBoxHeight As Integer = Math.Min(ListBox1.ItemHeight * ListBox1.Items.Count + 30, maxlistBoxHeight)
' Höhe der listBox setzen
ListBox1.Height = listBoxHeight
' Fensterhöhe anpassen (inkl. Puffer für Ränder)
Dim buttonSpacing As Integer = 10
Me.Height = ButtonOK.Height + 2 * buttonSpacing + ListBox1.Height + 50
End Sub
Private Sub ListBox_SelectedIndexChanged(sender As Object, e As EventArgs)
SelectedIndex = ListBox1.SelectedIndex
SelectedItem = CType(Items(SelectedIndex), T)
ButtonOK.Enabled = (SelectedIndex >= 0)
End Sub
Private Sub ButtonOK_Click(sender As Object, e As EventArgs)
Me.DialogResult = DialogResult.OK
Me.Close()
End Sub
Private Sub ButtonCancel_Click(sender As Object, e As EventArgs)
Me.DialogResult = DialogResult.Cancel
Me.SelectedIndex = -1
Me.Close()
End Sub
'Enumerator der Auswertungsarten
Private Enum Auswertungsart
AuswertungNichts
AuswertungString
AuswertungToString
AuswertungDisplayName
AuswertungName
End Enum
End Class
Public Interface IObjektAdapter
Function GetStringArray(items As IEnumerable, anzahl As Integer) As String()
End Interface
Class AssetAdapter
Implements IObjektAdapter
Public Function GetStringArray(items As IEnumerable, anzahl As Integer) As String() Implements IObjektAdapter.GetStringArray
Dim namen(anzahl - 1) As String
For i As Integer = 0 To anzahl - 1
namen(i) = CType(items(i), Asset).DisplayName
Next
Return namen
End Function
End Class
Falls Sie tiefergehende Beratung zu CAD-Methoden benötigen, klicken Sie bitte auf Kontakt.
Links anklicken um in die Zwischenablage kopieren:
Diese Seite: https://r-kon.de/cad-auswahldialog.php
Das Video: https://youtu.be/y739jWsr_fg (Youtube) / https://dai.ly/k4ssNpTHZtJkEhCvKHW (DailyMotion)
