Benutzer mit den meisten Antworten
Formular über einen string öffnen

Frage
Antworten
-
Die folgende Funktion durchsucht die aktuelle Assembly nach vorhandenen Formularen. Wenn ein Formular mit dem angegebenem Namen gefunden wurde, wird diese Form neu erzeugt (neue Instanz) und diese zurückgegeben.
Function ShowForm(ByVal FormName As String) As Form
_myAssembly = System.Reflection.Assembly.GetExecutingAssembly
'*** holt sich alle Typen die in der Assembly vorhanden sind_mytypes = _myAssembly.GetTypes
For Each mType As Type In _mytypes_Form = Activator.CreateInstance(mType)
'*** Schleife vorzeitig verlassen Exit For End If Next Return _Form End FunctionEin Aufruf könnte wie folgt aussehen:
Dim _myForm As Form
Dim _string As String'*** z.B.
_string =
"Form2"'*** suche nach der Form
_myForm = ShowForm(_string)
'*** Falls die Form gefunden wurde, diese anzeigen
If Not _myForm Is Nothing Then _myForm.Show()Ich hoffe das der Quellcode nachvollziehbar ist und Ihnen weiterhilft.
mfg.
Thomas Vujica
- Als Antwort vorgeschlagen Thorsten Dörfler Sonntag, 7. März 2010 10:17
- Als Antwort markiert Robert Breitenhofer Mittwoch, 17. März 2010 09:31
-
Mit welcher Anweisung wird aus dem _string eine ausführbare Form erzeugt? Ich habe so etwas ähnliches auch versucht.
Hallo Ellen,
die Instanz wird mit folgender Anweisung erzeugt:
_Form = Activator.CreateInstance(mType)
Vorher werden per Reflection die im Assembly verfügbaren Typen durchlaufen und überprüft, ob der Name des gesuchten Formulars mit dem gefundenen Typnamen übereinstimmt.
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort vorgeschlagen Ellen Ramcke Mittwoch, 10. März 2010 09:28
- Als Antwort markiert Robert Breitenhofer Mittwoch, 17. März 2010 09:32
-
Hallo Stefan,
das verwendet man u.a. dann, wenn man seine Anwendung in unabhängige Module aufteilen will.
Wobei die Technik nicht auf Formulare begrenzt ist, sondern über Reflection auf jeden Aspekt
ausgedehnt werden kann.
Ein Stichwort wäre dafür Plugin, siehe z. B.:
http://forum.vb-paradise.de/allgemeines/tipps-tricks-und-tutorials/allgemein/8747-wie-erstelle-ich-ein-plugin-system-unter-vb-net-framework-2/
http://www.vbarchiv.net/workshop/workshop_93-erstellen-von-plugins-zum-erweitern-eigener-programme.html
Gruß Elmar
- Als Antwort vorgeschlagen Ellen Ramcke Freitag, 12. März 2010 15:09
- Als Antwort markiert Robert Breitenhofer Mittwoch, 17. März 2010 09:32
Alle Antworten
-
Hallo Michael,
Was für Formulare möchtest du denn öffnen? Dateien kannst du in der Regel mit einem StreamReader einlesen und mit einem StreamWriter auf die Festplatte speichern. Um Zugang zu den Methoden zu erlangen musst du noch "Imports System.IO" vor deine classe setzten.
Hilft dir das?
LG
Tim -
Hallo Tim,
ich habe mich wahrscheinlich zu pauschal ausgedrückt. Nun, das Problem sieht so aus:
Ich lese eine Menüstruktur aus einer Datenbank ein (Treeview). Klicke ich nun auf einen der Nodes, soll
sich eine gleichlautende (treeview.selectednodes.text) Form öffnen.
treeview.selectednodes.text und Formname sind identisch, aber ich kriege die Kurve nicht vom String zur Form.
LG
Michael
-
das ist auch nicht mein Problem, sondern
dim aufzurufendeForm as string
aufzurufendeForm wird dann als string aus der Datenbank gelesen und ist z.B. "frmBestellungen"
aufzurufendeForm.show() geht aber nicht?
wahrscheinlich kleines Problem, aber große Wirkung? -
Die folgende Funktion durchsucht die aktuelle Assembly nach vorhandenen Formularen. Wenn ein Formular mit dem angegebenem Namen gefunden wurde, wird diese Form neu erzeugt (neue Instanz) und diese zurückgegeben.
Function ShowForm(ByVal FormName As String) As Form
_myAssembly = System.Reflection.Assembly.GetExecutingAssembly
'*** holt sich alle Typen die in der Assembly vorhanden sind_mytypes = _myAssembly.GetTypes
For Each mType As Type In _mytypes_Form = Activator.CreateInstance(mType)
'*** Schleife vorzeitig verlassen Exit For End If Next Return _Form End FunctionEin Aufruf könnte wie folgt aussehen:
Dim _myForm As Form
Dim _string As String'*** z.B.
_string =
"Form2"'*** suche nach der Form
_myForm = ShowForm(_string)
'*** Falls die Form gefunden wurde, diese anzeigen
If Not _myForm Is Nothing Then _myForm.Show()Ich hoffe das der Quellcode nachvollziehbar ist und Ihnen weiterhilft.
mfg.
Thomas Vujica
- Als Antwort vorgeschlagen Thorsten Dörfler Sonntag, 7. März 2010 10:17
- Als Antwort markiert Robert Breitenhofer Mittwoch, 17. März 2010 09:31
-
Hallo Michael,
so wie jedes andere Formular Deiner Anwendung auch, über die passende Objektreferenz. In dem Beispiel wäre das _MyForm.Close(). Innerhalb des Formulars wäre ferner Me.Close() das Mittel der Wahl, um das Formular per Code zu schließen.
Thorsten Dörfler
Microsoft MVP Visual Basic -
danke für die schnelle Antwort, jedoch hatte ich noch was vergessen - ich habe die Forms als SDI-Form innerhalb eines MDI-Fensters geöffnet und da läßt sich das SDI-Fenster nicht über _MyForm.close() schließen.
Function ShowForm(ByVal FormName As String, ByVal FormTitle As String) As Form
Dim _myAssembly As System.Reflection.Assembly
Dim _mytypes As Type()
Dim _Form As Form = Nothing
Dim _FormTitle As String = FormTitle
_myAssembly = System.Reflection.Assembly.GetExecutingAssembly
_mytypes = _myAssembly.GetTypes
For Each mType As Type In _mytypes
If mType.BaseType Is GetType(Form) AndAlso mType.Name = FormName Then
_Form = Activator.CreateInstance(mType)
_Form.MdiParent = MDI_Main
_Form.MinimizeBox =
False
_Form.MaximizeBox =
False
_Form.Text = _FormTitle
Exit For
End If
Next
Return _Form
End Function
-
Hallo Michael,
bei einem MDI Form kannst Du einfach über das aktuelle MDI Child gehen:
MDI_Main.ActiveMdiChild.Close()
Über die MdiChildren Eigenschaft des MDI Formulars hast Du zudem Zugriff auf alle Child Instanzen, die derzeit im MDI Container gehostet werden.
Thorsten Dörfler
Microsoft MVP Visual Basic -
Ich habe jetzt aber ein anderes Problem.
Mithilfe der o.g. Funktion habe ich ein Fenster innerhalb eines MDI-Containers geöffnet. Ich wechsel nun per Code in ein anderes Fenster. In diesem Fenster befindet sich ein Link zu einem Fenster, welches ich mit der o.g. Funktion wieder öffnen möchte. Nun wird natürlich eine weitere Kopie des Fensters erstellt. Ich möchte aber, dass ein bereits bestehendes Fenster geöffnet wird und wenn es nicht vorhanden ist, erst dann neu erstellt wird.
Könntet ihr mir nochmal eine Hilfestellung geben? -
Hallo Michael,
zwei Möglichkeiten: Du hinterlegst in der Tag-Eigenschaft Deiner geöffneten Formular eine eindeutige Kennung. Über die MdiChildren Eigenschaft iterierst Du durch alle MDI Childs und fragst diese Tag Eigenschaft ab, ob sie dem gesuchten Wert entspricht. Trifft das zu, hast Du Dein Formular.
Alternative: Du pflegst die Referenzen Deiner erzeugten Formulare in einem Dictionary. Als Schlüssel dient hier entweder der Formularname, wenn jedes Formular tatsächlich einmal vorhanden sein darf oder ein frei festlegbarer Schlüssel.
Grobes Beispiel:
Public Class MDI_Main Private m_MdiChilds As New Dictionary(Of String, Form) Public Function GetFoo() As Form Dim lMyForm As Form If m_MdiChild.ContainsKey("Foo") Then lMyForm = m_MdiChild.Item("Foo") Else lMyForm = ShowForm("frmFoo", "Foo") m_MdiChild.Add("Foo", lMyForm) End If Return lMyForm End Sub End Class
Thorsten Dörfler
Microsoft MVP Visual Basic -
Hallo Vujico,
ich habe eine Frage dazu.
Mit welcher Anweisung wird aus dem _string eine ausführbare Form erzeugt? Ich habe so etwas ähnliches auch versucht. Das ist gründlich schief gegangen.
Dann hätte ich noch einen alternativen Vorschlag zu machen.
Öffnen eines Formulars nicht über den String, sondern über einen Index.
Das würde so aussehen:
Dim _myForms as New List(Of Form) Dim Index = 1 ' Liste versorgen _myForms.Add(form2) ' Form starten über index if NOT _myForms(index) is Nothing then _myForms(index).Show()
was haltet Ihr davon
schöne Grüsse
Ellen -
Hallo Stefan,
so etwas nennt man, glaube ich, späte Bindung.
Die Festlegung welches Formular geöffnet wird geschieht nicht beim
Programmieren, sondern erst zur Laufzeit. In diesem Beispiel kommen
die Daten ja aus einer Datenbank. Die Daten entstehen erst im Programm
und nicht wenn Du programmierst.
OK, man kann das hier alles umgehen mit jeder Menge if then else Abfragen.
Aber das hier ist eleganter.
Ich habe so was ähnliches geschrieben, wo Controls zur Laufzeit dynamisch erzeugt werden.
das macht wirklich Sinn. Schau Dir das mal an
http://social.msdn.microsoft.com/Forums/de-DE/visualbasicde/thread/0e994166-2ed8-4a8e-af20-605a83c18111
schöne Grüße
Ellen -
Mit welcher Anweisung wird aus dem _string eine ausführbare Form erzeugt? Ich habe so etwas ähnliches auch versucht.
Hallo Ellen,
die Instanz wird mit folgender Anweisung erzeugt:
_Form = Activator.CreateInstance(mType)
Vorher werden per Reflection die im Assembly verfügbaren Typen durchlaufen und überprüft, ob der Name des gesuchten Formulars mit dem gefundenen Typnamen übereinstimmt.
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort vorgeschlagen Ellen Ramcke Mittwoch, 10. März 2010 09:28
- Als Antwort markiert Robert Breitenhofer Mittwoch, 17. März 2010 09:32
-
Hallo Stefan,
das verwendet man u.a. dann, wenn man seine Anwendung in unabhängige Module aufteilen will.
Wobei die Technik nicht auf Formulare begrenzt ist, sondern über Reflection auf jeden Aspekt
ausgedehnt werden kann.
Ein Stichwort wäre dafür Plugin, siehe z. B.:
http://forum.vb-paradise.de/allgemeines/tipps-tricks-und-tutorials/allgemein/8747-wie-erstelle-ich-ein-plugin-system-unter-vb-net-framework-2/
http://www.vbarchiv.net/workshop/workshop_93-erstellen-von-plugins-zum-erweitern-eigener-programme.html
Gruß Elmar
- Als Antwort vorgeschlagen Ellen Ramcke Freitag, 12. März 2010 15:09
- Als Antwort markiert Robert Breitenhofer Mittwoch, 17. März 2010 09:32
-
Hallo Thorsten,
ich habe deinen Code eingefügt und ihn ein wenig abgewandelt. Jetzt bekomme ich aber eine Exception, dass der Schlüssel bereits vergeben ist. An welcher Stelle wechsele ich zu einem bereits geöffneten Formular?
Mein Wunsch ist es doch nur eine SDI-Form per String aufrufen zu können (was ja jetzt geht) und zu dieser SDI-Form wechseln können, wenn diese bereits geladen ist.
Dim lMyForm As Form
If m_MdiChilds.ContainsKey(FormTitle) Then
lMyForm = m_MdiChilds.Item(FormTitle)
Else
lMyForm = ShowForm(FormName, FormTitle)
m_MdiChilds.Add(FormName, lMyForm)
End If
Return lMyForm
-
Hallo Michael,
es wäre von Vorteil, wenn Du auch überall den gleichen Schlüssel für das Dictionary verwenden würdest. Aktuell prüfst Du ob der FormTitle bereits im Dictionary vorhanden ist, fügst aber den FormName als Schlüssel hinzu. Kein Wunder also, dass Du so Duplikate bekommst, denn ContainsKey kann niemals True sein.
Dim lMyForm As Form If m_MdiChilds.ContainsKey(FormTitle) Then lMyForm = m_MdiChilds.Item(FormTitle) Else lMyForm = ShowForm(FormName, FormTitle) m_MdiChilds.Add(FormTitle, lMyForm) End If Return lMyForm
Thorsten Dörfler
Microsoft MVP Visual Basic -
PERFEKT
1000000 Dank
kann jetzt endlich weiterarbeiten ;-)
Ich habe noch eine zusätzliche Function anlegen müssen und zwar für den Fall, man schließt das SDI-Formular und möchte es später wieder öffnen:
Public
Function DeleteFoo(ByVal FormTitle As String) As Form
Dim dMyForm As Form
If m_MdiChilds.ContainsKey(FormTitle) = False Then
Exit Function
Else
dMyForm = m_MdiChilds.Item(FormTitle)
m_MdiChilds.Remove(FormTitle)
End If
Return dMyForm
End Function