Tooltip wird doppelt angezeigt / allgemeine Methode klappt nicht

  • VB.NET
  • .NET (FX) 4.0

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von tragl.

    Tooltip wird doppelt angezeigt / allgemeine Methode klappt nicht

    Hi zusammen.

    Ich hab' mir ne Methode gebaut, um mir ToolTips über Labels anzeigen zu lassen,
    dazu nutze ich die Tag-Eigenschaft der Labels - darin steht dann der entsprechende Tooltip-Text

    Einfache Variante: Funzt, ToolTips werden aber leider doppelt angezeigt:


    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "LabelToolTip"
    2. Public Sub RegisterLabelToolTip(ParamArray labels As Label())
    3. For Each lbl In labels
    4. AddHandler lbl.MouseHover, AddressOf lbl_mousehover
    5. Next
    6. End Sub
    7. Private Sub lbl_mousehover(sender As Object, e As EventArgs)
    8. Dim lbl = DirectCast(sender, Label)
    9. Dim tt As New ToolTip
    10. If Not lbl.Tag.ToString = "" Then tt.Show(lbl.Tag.ToString, lbl)
    11. End Sub
    12. #End Region 'LabelToolTip


    Aufruf im frm_Load
    RegisterLabelToolTip(StartKMLabel, EndKMLabel)





    Komplexere Variante: funzt derzeit nicht - hätte ich aber gerne, dann wäre das schön allgemein verwendbar:

    Spoiler anzeigen

    Und ich hätte das gerne noch allgemeiner, dann brauch ich nicht jedes Label per Hand registrieren. Vorgestellt hab ich mir das so:

    VB.NET-Quellcode

    1. #Region "LabelToolTip"
    2. <Extension>
    3. Public Sub RegisterLabelToolTip(frm As Form)
    4. Dim lstLBL = WalkThroughForm(frm)
    5. For Each lbl In lstLBL
    6. If Not lbl.Tag.ToString = "" Then AddHandler lbl.MouseHover, AddressOf lbl_mousehover
    7. Next
    8. End Sub
    9. Private Sub lbl_mousehover(sender As Object, e As EventArgs)
    10. Dim lbl = DirectCast(sender, Label)
    11. Dim tt As New ToolTip
    12. tt.Show(lbl.Tag.ToString, lbl)
    13. End Sub
    14. Private Function WalkThroughForm(frm As Form) As List(Of Label)
    15. Dim lstLBL As New List(Of Label)
    16. Dim recurse As Action(Of Control.ControlCollection) = Sub(ctlC As Control.ControlCollection)
    17. For Each ctl As Control In ctlC
    18. Dim lbl = TryCast(ctl, Label)
    19. If lbl IsNot Nothing Then
    20. lstLBL.Add(lbl)
    21. End If
    22. recurse(ctlC)
    23. Next
    24. End Sub
    25. recurse(frm.Controls)
    26. Return lstLBL
    27. End Function
    28. #End Region 'LabelToolTip


    Aufruf dann im Form-Load mit Me.RegisterLabelToolTip
    Ich muss den Aufbau ja irgendwie rekursiv durchgehen, denn die Labels sind echt verschachtelt:
    (es gibt aber sicher auch Forms bei mir, wo die Labels direkt draufliegen -> das muss damit ja dann auch funzen )

    Form -> Panel -> TableLayoutPanel -> GroupBox -> Label




    jemand eine Idee (am liebsten für die komplexe Lösung) + eine Idee dazu, dass die Labels nicht mehr doppelt angezeigt werden...
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „tragl“ ()

    @tragl Verwendest Du außerdem die ToolTips von der ToolTip-Component?
    Gib mal dem Tag einen anderen Text.
    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!

    RodFromGermany schrieb:

    @tragl Verwendest Du außerdem die ToolTips von der ToolTip-Component?
    Vermutlich, und das wäre die Erklärung für die Doppelung.



    @tragl: Die Tooltip-Komponente ist etwas eigentümlich.
    Entferne erstmal deinen selbstgebastelten Code, und lege im Designer für ein paar Labels iwelche Tooltips fest. (Label-Property 'TooltipText auf Tooltip1' setzen)
    Dann öffne die Designer.vb und guck nach, was der Designer da für Code generiert.
    Falls noch Bedarf zum Selber-coden besteht, halte dich an die Vorlage des DesignerCodes.

    tragl schrieb:

    VB.NET-Quellcode

    1. Dim tt As New ToolTip
    für jeden anzuzeigenden Text ist NoGo.



    Aber cool, mal eine anonyme rekursive Funktion zu sehen, die nicht von mir ist :thumbsup: (hab ich noch nie gesehen, obwohl ich bereits Tutorials dazu verfasst hab)
    Achmist - ist doch ein Fehler drin: in den rekursiven Aufruf musste natürlich ctl.Controls hineingeben - nicht ctlC - das würde ja eine EndlosRekursion.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ErfinderDesRades“ ()

    RodFromGermany schrieb:

    Verwendest Du außerdem die ToolTips von der ToolTip-Component?

    nein, die Property hab' ich nicht gefunden - deshalb selbst was geschrieben.
    ah grad gesehn - müsste ich im Designer aus der Toolbox ziehen und dann manuell alles machen.. will ich vermeiden, die ToolTips sollen evtl. "Hilfe-Dialoge" in meiner Anwendung vermeiden
    soll heißen wenn das sauber läuft werd' ich das wohl an sehr vielen Stellen einsetzen wollen ;)


    ErfinderDesRades schrieb:

    in den rekursiven Aufruf musste natürlich ctl.Controls hineingeben - nicht ctlC - das würde ja eine EndlosRekursion.

    danke, das war der Fehler - läuft nu.

    Allerdings werden die immernoch gedoppelt, teilweise sogar 3x und öfter dargestellt.
    Ich vermute mal, dass es an der Instanziierung liegt Dim tt As New ToolTip - beim ersten Hovern kommt 1x korrekt das ToolTip. Beim weiteren Hovern halt mehrere...

    ErfinderDesRades schrieb:

    für jeden anzuzeigenden Text ist NoGo.


    Wie wär' das anders zu lösen?
    Die Funktionierende Methode (außer dem Doppeln, Dreifachen etc.) ist nun wie folgt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. #Region "LabelToolTip"
    2. ''' <summary> erzeugt ein Tooltip bei Labels, dessen .Tag-Eigenschaft nicht Nothing ist </summary>
    3. <Extension>
    4. Public Sub RegisterLabelToolTip(frm As Form)
    5. Dim lstLBL = WalkThroughForm(frm)
    6. For Each lbl In lstLBL
    7. If lbl.Tag IsNot Nothing Then AddHandler lbl.MouseHover, AddressOf lbl_mousehover
    8. Next
    9. End Sub
    10. Private Sub lbl_mousehover(sender As Object, e As EventArgs)
    11. Dim lbl = DirectCast(sender, Label)
    12. Dim tt As New ToolTip
    13. tt.Show(lbl.Tag.ToString, lbl)
    14. End Sub
    15. Private Function WalkThroughForm(frm As Form) As List(Of Label)
    16. Dim lstLBL As New List(Of Label)
    17. Dim recurse As Action(Of Control.ControlCollection) = Sub(ctlC As Control.ControlCollection)
    18. For Each ctl As Control In ctlC
    19. Dim lbl = TryCast(ctl, Label)
    20. If lbl IsNot Nothing Then
    21. lstLBL.Add(lbl)
    22. End If
    23. recurse(ctl.Controls)
    24. Next
    25. End Sub
    26. recurse(frm.Controls)
    27. Return lstLBL
    28. End Function
    29. #End Region 'LabelToolTip
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Zwei Sachen - erstmal:

    ErfinderDesRades schrieb:

    Entferne erstmal deinen selbstgebastelten Code, und lege im Designer für ein paar Labels iwelche Tooltips fest. (Label-Property 'TooltipText auf Tooltip1' setzen)
    Probier das aus. Du wirst feststellen, dass Tooltips funktionieren, ohne dass du da mit einem eigenen Hover-Event dazwischengrätschst.
    Deswegen lass das, und lerne lieber, wie Tooltips wirklich ticken. Da braucht man kein Hover-Event, und auch kein .Show() aufzurufen - dassis kontraproduktiv.
    Oder muss ich erst eine SampleSolution bauen, damit du mitbekommst, wie einfach das ist?

    Zweitens:
    Bringt das was? Du musst ja nun irgendwas in die Tag-Eigenschaft der Controls schreiben. Da ists doch eiglich einfacher, im Designer die Controls anzuklicken, und deren TooltipText festzulegen - dann brauchste keinen Code dafür zu schreiben (und ausserdem bliebe die Tag-Property dann für ggfs. iwas anneres frei).

    ErfinderDesRades schrieb:

    Zwei Sachen - erstmal:

    OK ich muss zugeben - wusste nicht, dass das so einfach ist.
    Mein Gedanke ging dahin, dass ich für jedes Label einen ToolTip ausm Werkzeugkasten zaubern muss.
    Wenn ich das mit dem einen pro Form machen kann, dann umso besser ;)

    Aber der Vollständigkeit halber würde mich trotzdem interessieren, warum
    bei meiner Methode die Dinger doppelt und dreifach angezeigt werden.. :thumbup:
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    Beim Hovern hast du einen Tooltip erzeugt.
    Macht bei zweimal Hovern zwei Tooltips.
    Bei dreimal Hovern 3 Tooltips.

    ich sachja:

    ErfinderDesRades schrieb:

    tragl schrieb:

    VB.NET-Quellcode

    1. Dim tt As New ToolTip
    für jeden anzuzeigenden Text ist NoGo.


    Möglicherweise sinds auch mehr Tooltips als man sieht - weil sie vlt. übereinander liegen. Oder manchmal gehen welche auch nicht auf - ich empfinde dieses zeitverzögerte Hover-Verhalten nicht immer als 100% zuverlässig und reproduzierbar.
    Ich versteh den ganzen Aufwand nicht. Geh doch einfach von Anfang an alle Labels durch und setz für alle mit Tag-Eigenschaft den ToolTip:

    VB.NET-Quellcode

    1. Me.Controls.OfType(Of Label).Where(Function(x) x.Tag IsNot Nothing).ToList.ForEach(Sub(x) ToolTip1.SetToolTip(x, x.Tag.ToString))
    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.

    VaporiZed schrieb:

    Ich versteh den ganzen Aufwand nicht.

    Naja wie gesagt, ich wusste nicht dass das so einfach geht. Einmal ToolTip ausm Werkzeugfenster auf's Form gezogfen und schon kann ich den Text für jedes Label bei ToolTip1 eingeben.

    Reicht mir so, funzt auch einwandfrei. Ich wollte nur für mein Gewissen nachhaken ob das mit meiner Methode auch ginge ohne dass die doppelt / mehrfach angezeigt werden.
    Benutze jetzt die "einfache Variante" :D
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup: