Me.dispose & me.visible = false wird teilweise ignoriert

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Nils_Kr.

    Me.dispose & me.visible = false wird teilweise ignoriert

    Hi,

    ich habe ein UserControl mit diversen Buttons. Sobald dessen Funktion getriggert wurde soll das UserControl geschlossen werden.

    BsP:

    VB.NET-Quellcode

    1. Private Sub setThisMonth(sender As Object, e As EventArgs)
    2. 'doSth
    3. Me.Dispose()
    4. End Sub


    Das Verrückte ist, das doSth wird in jedem Fall ausgelöst wird, aber in ~50% der Fälle bleibt das UserControl einfach stehen. Bei me.Visible = false ist es genau das gleiche. Manchmal wird das Control unsichtbar, manchmal nicht. Der restliche Code im Sub wird immer ausgeführt :cursing:
    Option strict = on

    If it's stupid and it works it ain't stupid.
    @Nils_Kr Offensichtlich willst Du Dein Control durch sich selbst schließen lassen.
    Probiere das mal über ein Event an das Parent, dass dieses das Control disposed.
    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!

    ~blaze~ schrieb:

    Hi
    Am besten wäre alles, was mit der Methode interagieren könnte auf das wesentliche zusammengefasst.


    Da liegt glaube ich das Problem. Ich habe keine Ahnung, was da dazwischen funkt, es dürfte eigentlich nichts da sein.
    Wenn ich eine Schleife durch das ParentControl laufen lasse, wird das Usercontrol immer spätestens nach dem 2. Versuch gekillt.

    VB.NET-Quellcode

    1. Public Sub killUserControl()
    2. Dim isThere As Boolean = True
    3. While isThere
    4. isThere = False
    5. For Each ct As Control In Parent.Controls
    6. If TypeOf ct Is ModeSelector Then
    7. isThere = True
    8. Debug.WriteLine("usercontrol found!")
    9. ct.Dispose()
    10. End If
    11. Next
    12. End While
    13. End Sub


    So wird das Control erstellt (nennt sich ModeSelector):

    VB.NET-Quellcode

    1. Private Sub advLabelMouseEnter(sender As Object, e As EventArgs) Handles Me.MouseEnter
    2. Dim pt As New Point((Me.Parent.Location.X + Me.Location.X), (Me.Location.Y + Me.Parent.Location.Y + 25))
    3. Dim mS As New ModeSelector(mode)
    4. mS.Location = pt
    5. Parent.Parent.Controls.Add(MS)
    6. mS.Show()
    7. mS.BringToFront()
    8. End Sub


    Der Konstruktor:

    VB.NET-Quellcode

    1. Public Sub New(mode As Integer)
    2. InitializeComponent()
    3. TimerDelay.Start()
    4. Dim ds As MyDataSet = Mainform.MyDataSet
    5. Select Case mode
    6. Case 0
    7. LabelTitle.Text = "Filter:"
    8. Dim bt As New Button
    9. bt.Text = "alle Werte"
    10. AddHandler bt.Click, AddressOf setFilterAll
    11. FlowlayoutPanelMode.Controls.Add(bt)
    12. '...
    13. Case 1
    14. '...
    15. Case 2
    16. '...
    17. End Select
    18. End Sub


    das verknüpfte Event:

    VB.NET-Quellcode

    1. Private Sub setFilterAll(sender As Object, e As EventArgs)
    2. Mainform.activeChart.changeRange(-1)
    3. Me.Dispose()
    4. End Sub


    Habe den Timer auch schon manuell gestoppt, macht auch keinen Unterschied. Was neben dem Disposebefehl noch in aufgerufen wird ist egal, nur dispose funktioniert auch nicht immer. Ich habe alles andere, das noch in dem Control passiert deaktiviert.
    Option strict = on

    If it's stupid and it works it ain't stupid.

    Nils_Kr schrieb:

    VB.NET-Quellcode

    1. Parent.Parent.Controls.Add(MS)
    Sehe ich das richtig, dass Du da in Form3 ein Control instanziierst und es Form1 zuweist?
    Sende lieber von Form3 an Form1 ein Event mit den Daten oder der Instanz, dass das in der Form1-Instanz passiert.
    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!
    Ist alles auf einem Form. Getriggert wird das Ganze von einem Control(erbt von Label), das sich in einem FlowlayoutPanel befindet, welches sich in einem SplitcontainerPanel befindet. Das UserControl wird dann nicht dem FlowLayoutPanel, sondern dem SplitContainerPanel hinzugefügt. Sollte doch eigentlich unproblematisch sein oder?
    Option strict = on

    If it's stupid and it works it ain't stupid.

    Nils_Kr schrieb:

    spätestens nach dem 2. Versuch


    passiert das auch, wenn du das Steuerelement direkt im Konstruktor freigibst? Bzw. kannst du mal einen Haltepunkt festlegen, der in der Konsole ausgibt, wann aufgerufen wurde/wird (sprich davor und danach) und überprüfen, ob das korrekt abläuft?
    Dispose überschrieben hast du nicht oder wenn dann korrekt, oder? Du musst Dispose in jedem Fall nach oben weiterleiten (was bei return bzw. if ggf. nicht passiert).
    Beim Dispose sollte sich außerdem die Auflistung der Steuerelemente ändern, d.h. eigentlich sollte dort ein Fehler passieren.

    Übrigens: Handelt es sich bei dem Steuerelement um eine Art RadioButton?

    Viele Grüße
    ~blaze~
    Habs gefunden. MouseEnter triggert in 50% der Fälle doppelt und es liegen 2 Controls übereinander. Hätte ich mir eigentlich denken können, da MouseEnter & MouseLeave alles andere als zuverlässig arbeiten :rolleyes: (MouseLeave ist praktisch nutzlos).

    Mit Haltepunkt bemerkt man das leider nicht, da MouseEnter in diesem Fall ja nach dem ersten Aufruf anhält.
    Option strict = on

    If it's stupid and it works it ain't stupid.

    Nils_Kr schrieb:

    MouseEnter & MouseLeave alles andere als zuverlässig arbeiten (MouseLeave ist praktisch nutzlos).

    Das halte ich für eine sehr gewagte Aussage !
    Ich denke es wird immer korrekt getriggert, nur wird der Mousrcursor nicht immer präzise geführt.
    Für das Problem, könnte man sich aber ein Workaround überlegen.
    (Hmm - das kenn ich aber auch so, dass MouseEnter/Leave gelegentlich unzuverlässig sind - insbesondere bei schnellen Bewegungen.)

    Aber hier denke ich, gehört zum Problem, dass Controls generiert werden - das löst natürlich sofort ein MouseLeave aus, weil wenn das neue unter der Maus erscheint, ist die Maus nicht mehr über dem vorherigen Control.

    Ich rate ja immer vom dynamischen Control-Generieren ab - lieber nach konventionelleren Problemlösungen suchen.
    Aber bitte - probiert ruhig noch ein bischen :P

    FormFollowsFunction schrieb:


    Das halte ich f&uuml;r eine sehr gewagte Aussage !<br />


    Wenn man einen Cursor schlagartig aus einem Control herausbewegt, wird mouseLeave nicht getriggert, obwohl die Maus ganz eindeutig den Bereich des Controls verlassen hat. -> unzuverlässig. Meine Controls überprüfen inzwischen einfach kontiunierlich, ob der Cursor noch in der Nähe ist, da kann ich mir die Funktion sparen.

    ErfinderDesRades schrieb:


    Aber bitte - probiert ruhig noch ein bischen :P


    Funktioniert inzwischen sehr zuverlässig. Wenn man bei etwas komplexeren Anwendungen nicht mit zig Forms arbeiten will, sind dynamische Controls sehr praktisch.

    Option strict = on

    If it's stupid and it works it ain't stupid.