beliebige Controls für eine gewisse Zeit einfärben

  • VB.NET

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

    beliebige Controls für eine gewisse Zeit einfärben

    Hi,

    um dem Nutzer zu signalisieren, dass die Eingabe registriert wurde, lasse ich den Entsprechenden Button oder das parent Panel kurzzeitig einfärben. Die schnelle Variante wäre im Designer jeweils einen Timer anzulegen und mit dem entsprechenden Button zu verknüpfen.
    Nun nimmt die Anzahl der Funktionen mit Feedback zu und ich habe keine Lust dafür jedes Mal einen eigenen Timer anzulegen.

    Meine Idee war eine eigene Klasse anzulegen, der eine oder mehrere Controls übergeben werden, die dann jeweils einzufärben sind.
    So sieht das Ganze dann aus:

    VB.NET-Quellcode

    1. Public Class SaveFeedback
    2. Private ControlList As New List(Of Control)
    3. Private defaultColor As Color
    4. Dim timerSetBack As New Timer
    5. Public Sub New(clHighlight As Color, clDef As Color, cntrls As List(Of Control), intervalMs As Integer)
    6. AddHandler timerSetBack.Tick, AddressOf timersetback_tick
    7. timerSetBack.Interval = intervalMs
    8. ControlList = cntrls
    9. defaultColor = clDef
    10. For Each c As Control In ControlList
    11. c.BackColor = clHighlight
    12. Next
    13. timerSetBack.Start()
    14. End Sub
    15. Public Sub New(clHighlight As Color, clDef As Color, cntrl As Control, intervalMs As Integer)
    16. AddHandler timerSetBack.Tick, AddressOf timersetback_tick
    17. timerSetBack.Interval = intervalMs
    18. ControlList.Add(cntrl)
    19. defaultColor = clDef
    20. For Each c As Control In ControlList
    21. c.BackColor = clHighlight
    22. Next
    23. timerSetBack.Start()
    24. End Sub
    25. Private Sub timersetback_tick(sender As Object, e As EventArgs)
    26. For Each c As Control In ControlList
    27. c.BackColor = defaultColor
    28. Next
    29. ControlList.Clear()
    30. timerSetBack.Dispose()
    31. End Sub
    32. End Class


    Ein Aufruf sieht dann so aus:

    VB.NET-Quellcode

    1. Dim svFeedback As New SaveFeedback(Color.Lime, Color.Gainsboro, PanelActivityLogFoot, 1500)


    Funktioniert genauso wie es soll. Aber gibt es elegantere/effizientere Wege so einen allgemeinen Timer zu implementieren? Und reicht es den Timer zu killen, oder sollte das ganze Objekt für den GC freigegeben werden?
    Option strict = on

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

    Nils_Kr schrieb:

    oder sollte das ganze Objekt für den GC freigegeben werden?
    Lege das Objekt einmal für die Laufzeit an und starte den Timer, wenn sich Controls in der ControlList befinden und stoppe den Timer, wenn die Liste leer ist.
    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!
    Dazu müsste aber einiges etwas umgebaut werden.
    Letztendlich bräuchte man dann dafür nichtmal eine wirkliche Klasse, sondern eine Public Shared Methode, im Zusammenspiel mit ein paar private Shared Objekten täte reichen.

    Ansonsten, wenn du das Design so beibehalten willst, sollte der Timer sich unbedingt disposen, wenn er nicht mehr gebraucht wird. Alles weitere kann der GC alleine.

    RodFromGermany schrieb:

    Lege das Objekt einmal für die Laufzeit an und starte den Timer, wenn sich Controls in der ControlList befinden und stoppe den Timer, wenn die Liste leer ist.


    Das würde doch aber Probleme geben, wenn ich innerhalb eines Intervalls mehrere verschiedene Button drücke.

    ErfinderDesRades schrieb:

    Ansonsten, wenn du das Design so beibehalten willst, sollte der Timer sich unbedingt disposen, wenn er nicht mehr gebraucht wird. Alles weitere kann der GC alleine.


    Ok, der Timer wird schon disposed, wenn man den Rest so lassen kann passts ja.

    Wie soll ich mir die "paar" private Shared Objekte vorstellen?
    Option strict = on

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

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Nils_Kr“ ()

    @Nils_Kr Das zweite Zitat in Post #4 war vom @ErfinderDesRades , nicht von mir. ;)
    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!
    @Nils_Kr Da musst Du Dich zunächst festlegen, ob Du den Weg vom @ErfinderDesRades oder von mir einschlagen willst.
    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!
    Keine Ahnung. Der oben gepostete Code funktioniert ja genauso wie er soll. Mir geht es eher darum über den eigenen Tellerrand zu blicken und Herangehensweisen von Leuten mit mehr Erfahrung kennen zu lernen.

    Hatte das schon mal bei einem Thema zur Vererbung von Konstruktoren gemacht und da wurde einiges sehr interessante gepostet.
    Option strict = on

    If it's stupid and it works it ain't stupid.
    also das ist ein durchaus gangbarer Weg, für jedes Colorierungs-Ereignis ein eigenes Objekt zu erstellen, was dann dem GC anheimfällt, wenns sein Job gemacht hat.
    RFGs Ansatz "Singleton", oder meiner "Shared Class" sind glaub sogar etwas codierungs-aufwändiger, weil da die Vorgänge in einer Liste zu verwalten wären.
    Naja, und wenns Interessehalber ist, dann kannste dich ja für beide entscheiden, halt einen nach dem anneren.

    Ich täte aber vorschlagen, du stellst eine TestSolution ein, wo man das Dingens in Aktion sieht. Da kann man was dranbasteln, und dann hat Hand und Fuß, was geredet wird.

    Ausserdem interessiert mich, ob dein Dingens wirklich richtig funzt.
    IMO müsste es eiglich u.U. vorzeitig aufgeräumt werden, weil nach Erstellung vom Code nirgends mehr erreichbar.

    Anneres Problem ist, wenn mehrfach ins selbe Control eingegeben wird - entstehen da nicht mehrere solcher Dinger, und der eine macht aus, was der annere grad angemacht hat und sowas?

    Wie gesagt: TestSolution wäre interessant.

    Nils_Kr schrieb:

    Keine Ahnung.
    Da gebe ich dem @ErfinderDesRades Recht und wir operieren am lebenden Patienten. :D
    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!

    ErfinderDesRades schrieb:


    Anneres Problem ist, wenn mehrfach ins selbe Control eingegeben wird - entstehen da nicht mehrere solcher Dinger, und der eine macht aus, was der annere grad angemacht hat und sowas?


    In der Tat. Kritisch wird das, wenn man dem Objekt keine defaultColor gibt, sondern einfach die defaultColor des Controls übergibt. Wenn man dann mehrmals drückt, wird das Control dauerhaft eingefärbt. Ansonsten setzt sich die Farbe mit Abschluss des ersten Timers zurück, weiterhin passiert aber nichts.

    Im Anhang befindet sich ein kleines Bespielprojekt. Der mittlere Button funktioniert unter Win7 übrigens nicht, da Button erst ab Win8 eingefärbt werden können (wenn man nicht auf flat stellt).
    Dateien
    • FeedbackTest.rar

      (36,66 kB, 59 mal heruntergeladen, zuletzt: )
    Option strict = on

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

    Nils_Kr schrieb:

    Wenn man dann mehrmals drückt, wird das Control dauerhaft eingefärbt.
    Bei mir nicht (W10, VS2013).
    Wenn Du Dir ein Dictionary(Of Control, SaveFeedback) anlegst, kannst Du stets testen, ob es eine Instanz für das betreffende Control gibt, dann wird entweder keine neue Instanz angehängt oder es wird der betreffende Timer neu gestartet.
    Wie Du es brauchst.
    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:

    Bei mir nicht (W10, VS2013).

    Mit Dim svFeedback As New SaveFeedback(Color.Lime, Color.Gainsboro, PanelActivityLogFoot, 1500) passiert das auch nicht. Aber mit Dim svFeedback As New SaveFeedback(Color.Lime, PanelActivityLogFoot.BackColor, PanelActivityLogFoot, 1500) würde sich das Panel dauerhaft einfärben, wenn mehrmals innerhalb eines Zyklus getriggert wird.

    Das mit dem Dictionary klingt interessant, das werde ich mir mal genauer angucken.
    Option strict = on

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