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 Point
verwenden kann, bitte ich um Hinweis.
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)