Keyhandler zentral, Subs übergeben

  • VB.NET
  • .NET (FX) 4.0

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

    Keyhandler zentral, Subs übergeben

    Nabend.

    Ich nutze auf jeder Form mit DataGridView eigentlich den gleichen Keyhandler, deshalb kommt
    jetzt die Überlegung diesen an eine zentrale Stelle zu packen. Allerdings müsste ich Subs mit übergeben: (Edit und CreateNew sind die Subs, die auf der jeweiligen Form des DGV liegen)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub dgv_KeyDown(sender As Object, e As KeyEventArgs) Handles dgvMitarbeiterAbteilung.KeyDown,
    2. dgvAbteilung.KeyDown
    3. Dim dgv = DirectCast(sender, DataGridView)
    4. If e.KeyCode = Keys.P AndAlso e.Modifiers = Keys.Control Then
    5. 'Print
    6. ElseIf e.KeyCode = Keys.C AndAlso e.Modifiers = Keys.Control Then
    7. dgv.copyExportSelection(False)
    8. ElseIf e.KeyCode = Keys.A AndAlso e.Modifiers = Keys.Control Then
    9. dgv.SelectAll()
    10. ElseIf e.KeyCode = Keys.I AndAlso e.Modifiers = Keys.Control Then
    11. dgv.infoDGV
    12. End If
    13. Select Case e.KeyCode
    14. Case Keys.Enter : If dgvMitarbeiterAbteilung.ReadOnly Then Edit(dgv)
    15. Case Keys.Insert : CreateNew(dgv)
    16. Case Keys.Delete
    17. If User.MayDelete(_appMod) Then
    18. Dts.SaveDts()
    19. dgv.AllowUserToDeleteRows = True
    20. e.Handled = msgQuestionWarning("Die markierten Zeilen werden endgültig gelöscht, fortfahren?") = DialogResult.No
    21. Dts.SaveDts()
    22. Else
    23. msgDeleteDenied()
    24. e.Handled = True
    25. End If
    26. End Select
    27. End Sub


    Also sowas wie:

    Quellcode

    1. Public Sub RegisterDgvHandling(dgv As DataGridView, CreateNew As Sub, Edit As Sub)
    2. Addhandler dgv.KeyDown, AddressOf dgv_KeyDown
    3. End Sub
    4. Private Sub dgv_KeyDown(sender as Object, e as KeyEventArgs)
    5. Dim dgv = DirectCast(sender, DataGridView)
    6. If e.KeyCode = Keys.P AndAlso e.Modifiers = Keys.Control Then
    7. 'Print
    8. ElseIf e.KeyCode = Keys.C AndAlso e.Modifiers = Keys.Control Then
    9. dgv.copyExportSelection(False)
    10. ElseIf e.KeyCode = Keys.A AndAlso e.Modifiers = Keys.Control Then
    11. dgv.SelectAll()
    12. ElseIf e.KeyCode = Keys.I AndAlso e.Modifiers = Keys.Control Then
    13. dgv.infoDGV
    14. End If
    15. Select Case e.KeyCode
    16. Case Keys.Enter : If dgvMitarbeiterAbteilung.ReadOnly Then Edit(dgv)
    17. Case Keys.Insert : CreateNew(dgv)
    18. Case Keys.Delete
    19. If User.MayDelete(_appMod) Then
    20. Dts.SaveDts()
    21. dgv.AllowUserToDeleteRows = True
    22. e.Handled = msgQuestionWarning("Die markierten
    23. Zeilen werden endgültig gelöscht, fortfahren?") = DialogResult.No
    24. Dts.SaveDts()
    25. Else
    26. msgDeleteDenied()
    27. e.Handled = True
    28. End If
    29. End Select
    30. End Sub


    Gibt es eine Möglichkeit, Subs zu übergeben?
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup:
    docs.microsoft.com/de-de/dotne…ystem.action?view=net-5.0

    Evtl. wäre es sinnvoller die Methoden in eine eigene Klasse zu packen um deren Instanz als Parameter zu übergeben.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Das klappt erstmal nicht, da der KeyDownEventHandler eine feste Signatur hat. Man kann zwar Prozeduren als Parameter an andere Prozeduren übergeben, aber nicht bei EventHandlern.

    Ein Action-Beispiel

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Foo(0, Sub() Bar(DataGridView1)) 'es passiert nix
    3. Foo(1, Sub() Bar(DataGridView1)) 'Dgv-BackColor wird gesetzt
    4. Foo(2, Sub() Bar(DataGridView1)) 'es passiert nix
    5. End Sub
    6. Private Sub Foo(x As Integer, Action As Action)
    7. If x = 1 Then Action()
    8. End Sub
    9. Private Sub Bar(Dgv As DataGridView)
    10. Dgv.BackgroundColor = Drawing.Color.White
    11. End Sub


    Die Action, die der Prozedur Foo übergeben wird, ist in diesem Beispiel immer der Teil Sub() Bar(DataGridView1). Wenn x = 1 ist, wird also diese anonyme Prozedur aufgerufen, die dann wiederum Bar mit dem Parameter DataGridView1 aufruft. Und warum ruft man dann nicht gleich in Foo die Prozedur Bar mit dem Parameter DataGridView1 auf? Weil Foo DataGridView1 nicht kennen muss und die Action auch variieren kann:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Foo(0, Sub() DataGridView1.BackColor = Drawing.Color.White)
    3. Foo(1, Sub() TextBox1.Text = "Hallo")
    4. Foo(1, Sub() Button2.PerformClick)
    5. Foo(2, Sub() Me.Close)
    6. End Sub
    7. Private Sub Foo(x As Integer, Action As Action)
    8. If x = 1 Then Action()
    9. End Sub
    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.

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

    @tragl Du kannst den Eventhandler in einer anderen Klasse abonnieren, oder Du reichst das Event in Über-EventArgs gepackt, weiter.
    Wenn eine durchgereichte Prozedur aufgerufen werden soll, nimm Delegates:
    docs.microsoft.com/de-de/dotne…guage-features/delegates/
    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!
    @tragl Lässt Du uns an Deiner Lösung teil haben?
    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!
    Na klar, sorry...
    Wurd mit einer Extension von @ErfinderDesRades gelöst: , das sogenannte WeakAttachBase, da kann man dann alles Mögliche mit betreiben:

    VB.NET-Quellcode

    1. <Extension>
    2. Public Sub RegisterDgvHandling(Of T As {Form, New})(dgv As DataGridView, appMod As String)
    3. Dim att = dgv.Attach
    4. att.DGV = dgv
    5. att.DialogCreator = Function() New T
    6. att.AppMod = appMod
    7. Dim getChilds As Func(Of Control, IEnumerable) = Function(ctl) ctl.Controls '.Controls
    8. For Each ctl In getChilds.All(dgv.FindForm)
    9. Dim dgvC = TryCast(ctl, DataGridView)
    10. If dgvC.NotNull Then
    11. dgvC.registerDgvSettings
    12. dgvC.GetSetDgvColumnSettings(False, dgv.FindForm)
    13. End If
    14. Next
    15. End Sub
    16. <Extension()>
    17. Private Function Attach(dgv As DataGridView) As DataGridviewAttach
    18. Return DataGridviewAttach.Get(dgv)
    19. End Function


    VB.NET-Quellcode

    1. Public Class DataGridviewAttach : Inherits System.Runtime.CompilerServices.WeakAttachBase(Of DataGridviewAttach)
    2. Public WithEvents DGV As DataGridView
    3. Public AppMod As String
    4. Public DialogCreator As Func(Of Form)
    5. Private Sub dgv_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DGV.CellDoubleClick
    6. If Not e.RowIndex < 0 Then
    7. If User.MayEdit(AppMod) Then
    8. Using dlg = DialogCreator()
    9. DGV.ShowEditDialog(dlg)
    10. End Using
    11. End If
    12. End If
    13. End Sub
    14. Private Sub dgv_KeyDown(sender As Object, e As KeyEventArgs) Handles DGV.KeyDown
    15. Dim dgv = DirectCast(sender, DataGridView)
    16. If e.KeyCode = Keys.P AndAlso e.Modifiers = Keys.Control Then
    17. 'Print
    18. ElseIf e.KeyCode = Keys.C AndAlso e.Modifiers = Keys.Control Then
    19. dgv.copyExportSelection(False)
    20. ElseIf e.KeyCode = Keys.A AndAlso e.Modifiers = Keys.Control Then
    21. dgv.SelectAll()
    22. ElseIf e.KeyCode = Keys.I AndAlso e.Modifiers = Keys.Control Then
    23. dgv.infoDGV
    24. End If
    25. Select Case e.KeyCode
    26. Case Keys.Enter
    27. If Not User.MayEdit(AppMod) Then e.Handled = True
    28. If dgv.ReadOnly Then
    29. Using dlg = DialogCreator()
    30. dgv.ShowEditDialog(dlg)
    31. End Using
    32. End If
    33. Case Keys.Insert
    34. If Not User.MayCreateNew(AppMod) Then e.Handled = True
    35. Using dlg = DialogCreator()
    36. dgv.ShowCreateNewDialog(dlg)
    37. End Using
    38. Case Keys.Delete
    39. If User.MayDelete(AppMod) Then
    40. Dts.SaveDts()
    41. dgv.AllowUserToDeleteRows = True
    42. e.Handled = msgQuestionWarning("Die markierten Zeilen werden endgültig gelöscht, fortfahren?") = DialogResult.No
    43. Dts.SaveDts()
    44. Else
    45. msgDeleteDenied()
    46. e.Handled = True
    47. End If
    48. End Select
    49. End Sub
    50. End Class
    "Na, wie ist das Wetter bei dir?"
    "Caps Lock."
    "Hä?"
    "Shift ohne Ende!" :thumbsup: