Handles zur Laufzeit entfernen funktionert irgednwie nicht.

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Handles zur Laufzeit entfernen funktionert irgednwie nicht.

    Hallo,

    ich habe eine Funktion in einem Modul geschrieben, die für alle TextBoxen in einem als Parameter übergebenen Form einen Handler hinzufügen soll.

    VB.NET-Quellcode

    1. Friend Function mod_Functions_AddCommonHandlers(frmActiveForm As Form) As Boolean 'Das übergebene Form nach TabControls durchsuchen.
    2. Dim _handler As EventHandler = Sub(sender, e) mod_Functions_ControlContentChanged(sender, e, frmActiveForm) 'Lambda-Ausdruck
    3. For Each tc As TabControl In frmActiveForm.Controls
    4. 'Tab-Pages nach Windows-Forms-Controls durchsuchen.
    5. For Each tp As TabPage In tc.TabPages
    6. 'Windows-Forms-Controls
    7. For Each ctrl As Control In tp.Controls
    8. If TypeOf ctrl Is TextBox Then
    9. AddHandler ctrl.TextChanged, _handler
    10. End If
    11. Next ctrl
    12. Next tp
    13. Next tc
    14. Return True
    15. End Function

    Das funktionert auch soweit.
    Was nicht funktioniert ist der umgekehrte Weg

    VB.NET-Quellcode

    1. Friend Function mod_Functions_RemoveCommonHandlers(frmActiveForm As Form) As Boolean 'Das übergebene Form nach TabControls durchsuchen.
    2. Dim _handler As EventHandler = Sub(sender, e) mod_Functions_ControlContentChanged(sender, e, frmActiveForm) 'Lambda-Ausdruck
    3. For Each tc As TabControl In frmActiveForm.Controls
    4. 'Tab-Pages nach Windows-Forms-Controls durchsuchen.
    5. For Each tp As TabPage In tc.TabPages
    6. 'Windows-Forms-Controls
    7. For Each ctrl As Control In tp.Controls
    8. If TypeOf ctrl Is TextBox Then
    9. RemoveHandler ctrl.TextChanged, _handler
    10. End If
    11. Next ctrl
    12. Next tp
    13. Next tc
    14. Return True
    15. End Function

    'mod_Functions_RemoveCommonHandlers()' wird zwar fehlerfrei durchlaufen, die Handle bleiben aber aktiv. D.h. sobald ich den Text einer TextBox ändere wird weiterhin 'mod_Functions_ControlContentChanged()' aufgerufen.
    Wo liegt mein Fehler?
    @roepke Probierma dem Handler nach Wegnehmen der eigentlichen Prozedur eine leere Prozedur zuzuweisen.
    ====
    Was passiert, wenn Du das ganze in einer Form (nicht Modul) machst?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Du erzeugst hier zwei verschiedene Lamda (s?). Du kannst nicht Lamda1 hinzufügen und Lamda2 entfernen. Was passiert wenn AddCommonHandlers eine Instanz von Form1 übergeben wird und RemoveCommonHandlers eine Instanz von Form2? Eine Möglichkeit wäre das Lamda und die jeweilige Form in ein Dictionary zu packen.
    @roepke Deklariere den Eventhandler direkt ohne Lambda.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Naja, oder den Lambdaausdruck klassenmodulweit deklarieren und nicht 2x.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Erst mal vielen Dank für die Antworten.
    Habe das jetzt umgesetzt, mit einem Lambdaausdruck modulweit.
    Das scheint auch soweit zu funktionieren.
    Ein Frage habe ich aber noch.
    Mein Lambda sieht im Moment ja so aus:

    VB.NET-Quellcode

    1. Dim _handler As EventHandler = Sub(sender, e) mod_Functions_ControlContentChanged(sender, e, frmActiveForm)

    Jetzt möchte ich gerne eigene EventArgs ableiten um den zusätzlichen Parameter 'frmActiveForm' in die Argumente zu packen und die Standardsignatur zu verwenden.

    VB.NET-Quellcode

    1. Friend Class AddRemoveHandlerEventArgs : Inherits EventArgs
    2. Public ReadOnly frmActiveForm As Form
    3. Friend Sub New(frmActiveForm As Form)
    4. Me.frmActiveForm = frmActiveForm
    5. End Sub
    6. End Class

    Meine Sub sieht ja dann so aus:

    VB.NET-Quellcode

    1. Friend Sub ControlContentOrIndexChanged(ByVal sender As System.Object, ByVal e As AddRemoveHandlerEventArgs)

    Ich brauche in 'ControlContentOrIndexChanged' emplizit den Parameter 'frmActiveForm '.
    Wie muss ich mein Lambda anpassen, damit das funktioniert? Oder geht dass dann überhaupt noch per Lambda?
    So wird das ja auf jeden Fall nichts:

    VB.NET-Quellcode

    1. Dim _handler As EventHandler = Sub(sender, e) mod_Functions_ControlContentOrIndexChanged(sender, CType(e, AddRemoveHandlerEventArgs)) 'Lambda-Ausdruck

    weil das Objekt des Typs "System.EventArgs" ja nicht so einfach in den Typ "AddRemoveHandlerEventArgs" umgewandelt werden kann.
    Die Einrichtung der Handler erfolgt in:

    VB.NET-Quellcode

    1. Friend Function AddCommonHandlers(frmActiveForm As Form) As Boolean
    2. ...
    3. AddHandler uc_ctrl.TextChanged, _handler
    4. ...
    5. Return True
    6. End Function

    Irgendwie muss ich ja auch den Parameter 'frmActiveForm' in den '_handler' bekommen.
    Die Krux liegt wohl im 'e' des Sub() im Lambda?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „roepke“ ()