Object Type der feuernden Ereignisprozedur abfragen

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

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

    Object Type der feuernden Ereignisprozedur abfragen

    Hi,

    ich bin mir fast sicher, dass meine Frage ein Klax für die Experten ist. Mich hat es aber bisher ziemlichen Frust gekostet !

    Also .... ich habe eine Ereignisprozedur, die auf einen Button und einige CheckBoxes reagiert. Wenn der Button "Reshow" angeklickt wird oder wenn ich eine der Checkboxes ändere, dann soll ein bestimmtes Display neu erstellt werden.

    Soweit so gut.

    Jetzt habe ich aber eine Checkbox "All", die macht ein bissl mehr als nur das. Dies setzt alle Checkboxes auf "Checked" bzw. auf "not Checked". Dazu muss ich abfragen, ob DIESE Check Box geändert wurde. Das geht mit DirectCast(sender, Checkbox) und der Abfrage auf "is chkAll".

    Auch noch gut.

    Wenn ich jetzt aber cmdReshow klicke, dann scheitert das, weil der DirectCast (sender, Checkbox) nicht mehr funktioniert.

    NIcht mehr gut.

    Ich muss also den Typ der Control abfragen, welche das Event ausgelöst hat.

    Ich habe jetzt schon lange experimentiert ... aber nichts funktioniert. Hier mein jüngstes Coding:

    VB.NET-Quellcode

    1. Private Sub cmdReshow_Click(sender As Object, e As EventArgs) Handles cmdReshow.Click,
    2. chkShowConflicts.CheckedChanged,
    3. chkShowWarnings.CheckedChanged,
    4. chkShowMissmatches.CheckedChanged,
    5. chkShowTempAtObjects.CheckedChanged,
    6. chkAll.CheckedChanged
    7. If blnCheckDisabled Then Exit Sub 'Leave proc if disabled, to avoid recursion
    8. lblMessage.Text = ""
    9. 'Process chkAll.CheckChanged
    10. Dim myCtrl As Type = sender.GetType 'Get the type of control that had fired
    11. If TypeOf myCtrl Is CheckBox Then 'Ein Ausdruck vom Typ "Type kann nie vom Typ "Checkbox sein"
    12. Dim myCheck As CheckBox = DirectCast(sender, CheckBox) '<--- crashes when cmdReshow is clicked !
    13. If myCheck Is chkAll Then 'Select / Deselect all check boxes
    14. blnCheckDisabled = True 'Run check disabled
    15. chkShowConflicts.Checked = chkAll.Checked 'Set checkboxes ....
    16. chkShowWarnings.Checked = chkAll.Checked
    17. chkShowMissmatches.Checked = chkAll.Checked
    18. chkShowTempAtObjects.Checked = chkAll.Checked
    19. blnCheckDisabled = False 'Reenable check
    20. End If
    21. End If
    22. 'Common processing
    23. chkShowConflicts.ForeColor = If(chkShowConflicts.Checked, SystemColors.ControlText, Color.Red)
    24. chkShowWarnings.ForeColor = If(chkShowWarnings.Checked, SystemColors.ControlText, Color.Red)
    25. chkShowMissmatches.ForeColor = If(chkShowMissmatches.Checked, SystemColors.ControlText, Color.Red)
    26. chkShowTempAtObjects.ForeColor = If(chkShowTempAtObjects.Checked, SystemColors.ControlText, Color.Red)
    27. DisplayObjectsList() 'Redisplay object list
    28. UpdateObjectList() 'Update objects in list
    29. End Sub


    Mit TypeOf myCtrl Is CheckBox geht es also nicht ... auch nicht mit Gettype() etc. etc.

    Wie frage ich denn den Type dieser vermaledeiten Control ab ?

    Ich hoffe, ihr könnt mir wir immer nachsichtig auf die Sprünge helfen! :)

    LG
    Peter

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

    TryCast wäre hier eigt. eher der richtige Ansatz.

    Aber eigentlich ist das sowieso schlecht. Das müsstest du schon aufteilen. Ich würde z.B. 23-26 jeweils in das Event der jeweiligen CheckBox und 27-28 gehört dabei auch in jedes rein. Wenn du dabei dann doppelt ausführung von 27-28 machen möchtest, dann musst du dies ähnlich wie bereits jetzt auch über eine bool variable machen.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    MrTrebron schrieb:

    Kann es sein das cmdReshow ein Button ist? Der kann dann nicht zu Checkbox Konvertiert werden. Dies musst du vorher prüfen.


    Na klar ist das ein Button ... das ist ja gerade das Problem. :) Man Frage ist doch gerade WIE man das prüfen kann.

    MrTrebron schrieb:

    TryCast wäre hier eigt. eher der richtige Ansatz.


    Jau, mit TryCast schnuckelt die Sache. Und wie man ansonsten die Sache mit der Prüfung umgehen kann, das ist mir schon klar. Eigentlich geht es mir jetzt eher noch darum, das allgemeine Problem zu lösen, wie man den Type einer Control abfragen kann ...

    Ansonsten bin ich mit der TryCast Lösung für diesen speziellen Fall vollkommen zufrieden. Danke ! :)

    Peter329 schrieb:

    Mit TypeOf myCtrl Is CheckBox geht es also nicht ... auch nicht mit Gettype() etc. etc.

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, CheckBox1.CheckedChanged, CheckBox2.CheckedChanged
    2. If sender.GetType() Is GetType(Button) Then
    3. Dim btn = DirectCast(sender, Button)
    4. If sender Is Button1 Then
    5. Label1.Text = "Button1"
    6. ElseIf sender Is Button2 Then
    7. Label1.Text = "Button2"
    8. End If
    9. ElseIf sender.GetType() Is GetType(CheckBox) Then
    10. Dim cb = DirectCast(sender, CheckBox)
    11. If sender Is CheckBox1 Then
    12. Label1.Text = "CheckBox1"
    13. ElseIf sender Is CheckBox2 Then
    14. Label1.Text = "CheckBox2"
    15. End If
    16. End If
    17. End Sub

    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!
    If sender.GetType() Is GetType(CheckBox) Then ...

    Genau das war es was ich gesucht hatte ! Wenn man es so sieht, dann scheint es ganz naheliegend. :)

    Ein um's andere Mal recht herzlichen Dank !

    LG
    Peter
    @Peter329 Du solltest Dir mal eine Snippet-Sammlung zulegen.
    Snippets\TypeOf\TypeOf.vb mit diesem Inhalt und dem Link von diesem Thread.
    Manchmal ein kleines Projekt, immer sorgfältig soetiert.
    Bei mir sieht das so aus:
    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!
    Das finde ich jetzt zwar ein bisschen komisch.

    VB.NET-Quellcode

    1. If TypeOf myCtrl Is CheckBox Then

    Dass das nicht funktionieren kann versteh ich, da myCtrl in Type-Datentyp ist.

    Das hier sollte aber gehen, da sender vom Typ Object ist. Es entspricht genau dem, was RFG vorgeschlagen hat.

    VB.NET-Quellcode

    1. If TypeOf sender Is CheckBox Then
    2. 'oder
    3. If sender.GetType() Is GetType(CheckBox) Then


    Freundliche Grüsse

    exc-jdbi
    Schön nimm den einfachen weg und ignorier wie man es richtig programmieren würde.
    Ansonsten klar geht es über die Typ überprüfung. Aber in den meisten Fällen braucht man das nicht und immer wenn du erst den Typ überprüfst und anschließend zu diesem Typ castest, dann nimmt man TryCast. Erstens versteht man damit direkt was gemacht werden soll und andererseits ist es um einiges performanter.

    Edit: btw. mit nicht einfachem Weg mein ich weder TryCast noch GetType, sondern eben komplett ohne diese beiden Lösungen, was durchaus gut und übersichtlich möglich ist...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    Peter329 schrieb:

    wie man den Type einer Control abfragen kann ...
    Wieso willst du den Typ abfragen?
    Also was Rod gecodet hat ginge einfacher so:

    VB.NET-Quellcode

    1. Private Sub Any_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, CheckBox1.CheckedChanged, CheckBox2.CheckedChanged
    2. Select Case True
    3. Case sender Is Button1
    4. Label1.Text = "Button1"
    5. Dim bt = DirectCast(sender, Button)
    6. '...
    7. Case sender Is Button2
    8. Label1.Text = "Button2"
    9. Dim bt = DirectCast(sender, Button)
    10. '...
    11. Case sender Is CheckBox1
    12. Label1.Text = "CheckBox1"
    13. Dim ck = DirectCast(sender, CheckBox)
    14. '...
    15. Case sender Is CheckBox2
    16. Label1.Text = "CheckBox2"
    17. Dim ck = DirectCast(sender, CheckBox)
    18. '...
    19. End Select
    20. End Sub
    Also du brauchst den Typ nicht abzufragen.
    Wenn du weisst, dass Sender Checkbox1 ist, kannst du direkt casten - da kanns ja kein Vertun geben.
    @ErfinderDesRades Ich hatte es so verstanden, dass @Peter329 die Gruppen Button und CheckBox auch als solche ansprechen will.
    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!
    Also erst nochmal einen schönen Dank, für die Anregungen

    jvbsl schrieb:

    Schön nimm den einfachen weg und ignorier wie man es richtig programmieren würde.


    Also ich ignoriere keinen Ratschlag ... ich versuche halt Dinge so umzusetzen, wie ich dazu in der Lage bin. :)

    So hab ich das jetzt kodiert:

    VB.NET-Quellcode

    1. Private Sub cmdReshow_Click(sender As Object, e As EventArgs) Handles cmdReshow.Click,
    2. chkShowConflicts.CheckedChanged,
    3. chkShowWarnings.CheckedChanged,
    4. chkShowMissmatches.CheckedChanged,
    5. chkShowTempAtObjects.CheckedChanged,
    6. chkAll.CheckedChanged
    7. If blnCheckDisabled Then Exit Sub 'Leave proc if disabled (avoid recursion)
    8. lblMessage.Text = ""
    9. 'Process chkAll.CheckChanged
    10. If sender Is chkAll Then 'Select / Deselect all other check boxes
    11. chkShowConflicts.Checked = chkAll.Checked
    12. chkShowWarnings.Checked = chkAll.Checked
    13. chkShowMissmatches.Checked = chkAll.Checked
    14. chkShowTempAtObjects.Checked = chkAll.Checked
    15. blnCheckDisabled = False 'Reenable check
    16. End If
    17. 'Common processing
    18. chkShowConflicts.ForeColor = If(chkShowConflicts.Checked, SystemColors.ControlText, Color.Red)
    19. chkShowWarnings.ForeColor = If(chkShowWarnings.Checked, SystemColors.ControlText, Color.Red)
    20. chkShowMissmatches.ForeColor = If(chkShowMissmatches.Checked, SystemColors.ControlText, Color.Red)
    21. chkShowTempAtObjects.ForeColor = If(chkShowTempAtObjects.Checked, SystemColors.ControlText, Color.Red)
    22. DisplayObjectsList() 'Redisplay object list
    23. UpdateObjectList() 'Update objects in list
    24. End Sub


    Ich finde, das ist eine sehr schöne Lösung für die häufige Aufgabe, mehrere Checkboxes abzuhandeln und insbesondere alle auf einen Schlag auswählen oder abwählen zu können. Jede notwendige Anweisung wird genau einmal kodiert und alles wird zentral in einer Prozedur abgewickelt.

    Ohne euch hätte ich das nicht so elegant hinbekommen. Ich bin begeistert ... ihr habt mein Vertrauen, das ich eingangs geäußert hatte, nicht enttäuscht! :)

    LG
    Peter