Benutzer mit den meisten Antworten
SteuerElement (zb.Button) zur Laufzeit erstellen und auch ansprechen mit WithEvents. Warum geht das nicht ????

Frage
-
Hallo ihrs
Ich beschäftige mich gerade damit, Steuerelemente zur Laufzeit erstellen und möchte diese auch gerne ansprechen. Ich weiß mittlereweile das ich die erstellten Steuerelemente mit zb. "AddHandler.Click,AdressOf ......." ansprechen kann. Nun habe ich aber in einem Vb6 Beispielgesehen das das ganze auch mit WithEvents ansprechen kann, und dachte mir das muss doch auch in VB8 gehen. und habe folgendes probiert.Public Class Form1 Private WithEvents MeinButton As Button Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim MeinButton As New Button With MeinButton .Text = " OK " .BringToFront() .Left = 100 .Top = 100 Me.Controls.Add(MeinButton) End With End Sub Private Sub MeinButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MeinButton.Click MsgBox("Der Button wurde geklickt") End Sub End Class
Sicherlich habe ich nur einen Denkfehler oder sollte das mit WithEvents unter VB8 wirklich nicht gehen.
Kann mir das mal Jemand erklären bzw Zeigen wie es Richtig sein sollte???
Lg Wild-Life78
Antworten
-
Um auf einen bestimmten selbst erstellten Button zuzugreifen, kannst Du diesen bspw. einen Namen geben:
Dim lButton As New Button() lButton.Name = "DynamicButton1" '... Me.Controls.Add(lButton)
Später kannst Du dann über diesen Namen die Controlreferenz in der Controls-Auflistung ausfindig machen:
Debug.Print(DirectCast(Me.Controls("DynamicButton1"), Button).Text)
Es kann aber auch sinnvoll sein, eine eigene Auflistung aller zusammengehörenden Buttons bzw. dynamischen Controls zu verwalten:
Private m_MyButtons As New List(Of Button) Private Sub Form_Load ... Dim lButton = New Button() lButton .Text = "My Button 1" lButton .Name = "MyButton1" lButton .Visible = True Me.Controls.Add(lButton) m_MyButtons.Add(lButton) End If ' ... Debug.Print(m_MyButtons(0).Text)
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort markiert Wild-Life78 Dienstag, 3. November 2009 18:46
-
Lass die erneute Deklaration von
Dim MeinButton As New Button
innerhalb von Form_Load weg. Damit weist Du die Referenz auf Deinen Button einer privaten Variable zu. Die Klassenvariable "MeinButton" bekommt davon nichts mit, somit empfängt sie auch keine Ereignisse Deines Button.
Scope in Visual Basic
http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx
Wenn Du wirklich dynamisch werden möchtest, stößt Du mit WithEvents schnell an die Grenzen. Über AddHandler kannst Du Ereignisse völlig dynamisch auf eigene Methoden aufsetzen, ohne zur Designzeit wissen zu müssen, wie viele Instanzen Du später einmal haben wirst:
AddHandler Statement
http://msdn.microsoft.com/en-us/library/7taxzxka.aspx
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort markiert Wild-Life78 Sonntag, 1. November 2009 18:41
- Tag als Antwort aufgehoben Wild-Life78 Montag, 2. November 2009 14:31
- Als Antwort vorgeschlagen Thorsten DörflerModerator Montag, 2. November 2009 18:56
- Als Antwort markiert Wild-Life78 Dienstag, 3. November 2009 14:37
-
Hallo Ronny,
das hat nichts mit innerhalb oder außerhalb der Klasse zu tun, sondern rein mit Dynamik. Wenn Du zur Entwicklungszeit sagst:
Private WithEvents MyButton As Button
Kannst Du zur Laufzeit immer nur exakt eine Button Instanz über diese Variable "MyButton" referenzieren:
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load MyButton = New Button() With MyButton .Text = " OK " .Left = 100 .Top = 100 End With Me.Controls.Add(MyButton) End Sub Private Sub MyButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MeinButton.Click MsgBox("Der Button wurde geklickt") End Sub
Jetzt stellst Du aber fest, dass Du zur Entwicklungszeit gar nicht wissen kannst, wie viele Buttons Du tatsächlich benötigst. Mal reicht einer, mal brauchst du 2, 3 oder sogar 5. Dann bist Du mit WithEvents am Ende, wenn Du nicht auf Verdacht 5 WithEvent Variablen deklarieren möchtest. Hier verwendest Du dann AddHandler. Zunächst brauchst Du weiterhin eine Methode, die als Ereignisempfänger fungiert:
Private Sub AnyButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Dim lText As String = DirectCast(sender, Button).Text MsgBox(String.Format("Der Button '{0}' wurde geklickt", lText)) End Sub
Wie Du siehst, ist hier die Handles Anweisung nicht mehr notwendig.
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load For i As Integer = 0 To 4 Dim lButton = New Button() With lButton .Text = String.Format("Button {0}", i + 1) .Left = 100 .Top = 100 + (25 * i) End With AddHandler lButton.Click, AddressOf AnyButton_Click Me.Controls.Add(lButton) Next End Sub
Hoffe das Beispiel veranschaulicht den Unterschied etwas besser. Wenn Du noch Fragen hast, scheue nicht sie zu stellen.
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort vorgeschlagen Thorsten DörflerModerator Montag, 2. November 2009 18:56
- Als Antwort markiert Wild-Life78 Dienstag, 3. November 2009 14:36
Alle Antworten
-
Lass die erneute Deklaration von
Dim MeinButton As New Button
innerhalb von Form_Load weg. Damit weist Du die Referenz auf Deinen Button einer privaten Variable zu. Die Klassenvariable "MeinButton" bekommt davon nichts mit, somit empfängt sie auch keine Ereignisse Deines Button.
Scope in Visual Basic
http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx
Wenn Du wirklich dynamisch werden möchtest, stößt Du mit WithEvents schnell an die Grenzen. Über AddHandler kannst Du Ereignisse völlig dynamisch auf eigene Methoden aufsetzen, ohne zur Designzeit wissen zu müssen, wie viele Instanzen Du später einmal haben wirst:
AddHandler Statement
http://msdn.microsoft.com/en-us/library/7taxzxka.aspx
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort markiert Wild-Life78 Sonntag, 1. November 2009 18:41
- Tag als Antwort aufgehoben Wild-Life78 Montag, 2. November 2009 14:31
- Als Antwort vorgeschlagen Thorsten DörflerModerator Montag, 2. November 2009 18:56
- Als Antwort markiert Wild-Life78 Dienstag, 3. November 2009 14:37
-
Hallo, Nun war ich etwas zu voreillig,
also AddHandler ist die bessere Version, innerhalb der Klasse komme ich auch gut damit klar, aber wenn ich Dich richtig verstanden habe meinst Du mit dynamisch ausserhalb der Klasse? Das verstehe ich nicht ganz bzw bekomme es nicht hin. Ist Dir oder Jemanden der es weiß möglich, mal ein kleines Beisspiel zu zeigen, bzw mein Beispiel so umzubauen, damit ich etwas besser verstehe wie Du das meinst???
Ps selbstverständlich war Deine Antwort sicherlich richtig, aber ich habe es glaube noch nicht so ganz verstanden, ich werde Deinen Beitrag auch wieder als Antwort markieren, habe die Antwort nur zurück gezogen damit der Beitrag nochmal gelesen wird.
Gruß Ronny -
Hallo Ronny,
das hat nichts mit innerhalb oder außerhalb der Klasse zu tun, sondern rein mit Dynamik. Wenn Du zur Entwicklungszeit sagst:
Private WithEvents MyButton As Button
Kannst Du zur Laufzeit immer nur exakt eine Button Instanz über diese Variable "MyButton" referenzieren:
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load MyButton = New Button() With MyButton .Text = " OK " .Left = 100 .Top = 100 End With Me.Controls.Add(MyButton) End Sub Private Sub MyButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MeinButton.Click MsgBox("Der Button wurde geklickt") End Sub
Jetzt stellst Du aber fest, dass Du zur Entwicklungszeit gar nicht wissen kannst, wie viele Buttons Du tatsächlich benötigst. Mal reicht einer, mal brauchst du 2, 3 oder sogar 5. Dann bist Du mit WithEvents am Ende, wenn Du nicht auf Verdacht 5 WithEvent Variablen deklarieren möchtest. Hier verwendest Du dann AddHandler. Zunächst brauchst Du weiterhin eine Methode, die als Ereignisempfänger fungiert:
Private Sub AnyButton_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Dim lText As String = DirectCast(sender, Button).Text MsgBox(String.Format("Der Button '{0}' wurde geklickt", lText)) End Sub
Wie Du siehst, ist hier die Handles Anweisung nicht mehr notwendig.
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load For i As Integer = 0 To 4 Dim lButton = New Button() With lButton .Text = String.Format("Button {0}", i + 1) .Left = 100 .Top = 100 + (25 * i) End With AddHandler lButton.Click, AddressOf AnyButton_Click Me.Controls.Add(lButton) Next End Sub
Hoffe das Beispiel veranschaulicht den Unterschied etwas besser. Wenn Du noch Fragen hast, scheue nicht sie zu stellen.
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort vorgeschlagen Thorsten DörflerModerator Montag, 2. November 2009 18:56
- Als Antwort markiert Wild-Life78 Dienstag, 3. November 2009 14:36
-
Ja, das Beispiel ist gut und vorallem verständlich, ich wünschte solche Beispiele wären in Msdn Liybary zu finden, denn mal ganz ehrlich, manche Sachen dort, werden unwarscheinlich kompliziert dargestellt und erklärt, obwol sie eigentlich ganz einfach sind.
Was die weiteren Fragen betrifft, da kommen bestimmt noch welche, aber dieses Problem hier, ist jetzt erstmal keins mehr. (-:
obwohl vieleicht kannst mir noch sagen wie ich jetzt, zb nur Button3 von den 5 Button anspreche ?
Vielen Dank
Gruß Ronny -
Um auf einen bestimmten selbst erstellten Button zuzugreifen, kannst Du diesen bspw. einen Namen geben:
Dim lButton As New Button() lButton.Name = "DynamicButton1" '... Me.Controls.Add(lButton)
Später kannst Du dann über diesen Namen die Controlreferenz in der Controls-Auflistung ausfindig machen:
Debug.Print(DirectCast(Me.Controls("DynamicButton1"), Button).Text)
Es kann aber auch sinnvoll sein, eine eigene Auflistung aller zusammengehörenden Buttons bzw. dynamischen Controls zu verwalten:
Private m_MyButtons As New List(Of Button) Private Sub Form_Load ... Dim lButton = New Button() lButton .Text = "My Button 1" lButton .Name = "MyButton1" lButton .Visible = True Me.Controls.Add(lButton) m_MyButtons.Add(lButton) End If ' ... Debug.Print(m_MyButtons(0).Text)
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort markiert Wild-Life78 Dienstag, 3. November 2009 18:46