Datagridview nach Edit selektierte Zeile beibehalten

  • VB.NET
  • .NET 4.5

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

    Datagridview nach Edit selektierte Zeile beibehalten

    Hi,

    ich will mal versuchen mein Problem verständlich zu machen. Ich hoffe ihr seid geduldig .... :)

    Ich habe eine Datagridview, deren Zeilen ich per FullRowSelect selektiere.

    Wie üblich kann man durch Anklicken einer Zelle in den EditMode wechseln und den Inhalt der Zeile verändern.

    Den EditMode kann man (u.a.) durch das Drücken der RETURN oder ENTER Taste wieder beenden.

    Soweit so gut. Nun zu meinem Problem:

    Wenn man RETURN oder ENTER drückt, wird nicht nur der EditMode beeendet, sondern es wird auch die NÄCHSTE ZEILE selektiert.

    Das mag für viele Anwendungen genau das Richtige sein ... in meinem Fall ist das aber nicht erwünscht ! Ich habe mir also Gedanken gemacht, wie ich die selektierte Zeile nach EndEdit beibehalten kann.

    Die ausgewählte Zeile kann ich mir im BeginEdit Event als e.rowindex merken. Das ist schon mal gut.

    Die Idee, diese Auswahl etwa im EndEdit Event zu restaurieren scheitert aber ... weil im EndEdit das Feld e.rowIndex immer noch auf die gleiche Zeile zeigt ! Offensichtlich erfolgt der Zeilenvorschub erst später.

    Was darüber hinaus problematisch ist: Ich erhalte keine Information darüber, ob der EditMode mit ENTER / RETURN beendet wurde (das kann nämlich auch durch die ESC Taste oder einen MausClick erfolgen !)

    Ich habe das Ganze in einem kleinen TestProject abgebildet.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    3. DataGridView1.Rows.Add("Mueller", "Peter")
    4. DataGridView1.Rows.Add("Meyer", "Hans")
    5. DataGridView1.Rows.Add("Schmidt", "Walter")
    6. DataGridView1.Rows.Add("Schuster", "Kurt")
    7. DataGridView1.ClearSelection()
    8. End Sub
    9. Private Sub DataGridView1_KeyDown(sender As Object, e As KeyEventArgs) Handles DataGridView1.KeyDown
    10. Debug.Print("KeyDown - " & e.KeyCode.ToString)
    11. End Sub
    12. Private Sub DataGridView1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles DataGridView1.KeyPress
    13. Debug.Print("KeyPress" & e.KeyChar.ToString)
    14. End Sub
    15. Private Sub DataGridView1_CellBeginEdit(sender As Object, e As DataGridViewCellCancelEventArgs) Handles DataGridView1.CellBeginEdit
    16. Debug.Print("CellBeginEdit - Row Index Start: " & e.RowIndex.ToString)
    17. End Sub
    18. Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    19. If TypeOf e.Control Is DataGridViewTextBoxEditingControl Then
    20. AddHandler DirectCast(e.Control, DataGridViewTextBoxEditingControl).KeyPress, AddressOf Control_KeyPress
    21. End If
    22. End Sub
    23. Public Sub Control_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs)
    24. Debug.Print("Control_KeyPress - my Char=" & e.KeyChar.ToString &
    25. " &H" & Convert.ToString(Convert.ToInt32(e.KeyChar), 16))
    26. End Sub
    27. Private Sub DataGridView1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
    28. Debug.Print("CellEndEdit - Row Index End: " & e.RowIndex.ToString)
    29. End Sub
    30. End Class


    Ich ersetze "Hans" durch "Lee"und drücke die RETURN Taste um den Update abzuschließen .... damit erhalte ich das folgende Debug Protokoll:

    Quellcode

    1. CellBeginEdit - Row Index Start: 1
    2. Control_KeyPress - my Char=L &H4c
    3. Control_KeyPress - my Char=e &H65
    4. Control_KeyPress - my Char=e &H65
    5. CellEndEdit - Row Index End: 1


    Die Zeilenauswahl steht danach auf der nächsten Zeile (s. Screenshot).

    Wie man sieht habe ich im Debugging weder Informationen über das Drücken der Return Taste noch über den Wechsel auf die Zeile mit dem Index 2.

    Wie kann man denn diesen vermaledeiten Zeilenwechsel verhindern ?

    Umgehen lässt sich das Problem, indem man den EditMode nicht mit der RETURN Taste beendet, sondern etwa mit der Maus auf ein anderes Feld in der gleichen Zeile klickt. Die meisten Leute sind es aber gewohnt, Änderungen mit RETURN / ENTER zu beenden ... deshalb ist diese Umgehung nicht so gut !

    LG
    Peter
    Bilder
    • s 2019-10-10 09-49-132.jpg

      14,4 kB, 424×212, 4 mal angesehen

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

    Ein erster Workaround, den ich immer gern verwende, wenn anscheinend kein Event mehr folgt, welches man hernehmen könnte: Mit Async/Await kurz warten:

    VB.NET-Quellcode

    1. Private Async Sub DataGridView1_CellEndEdit(sender As Object, e As EventArgs) Handles DataGridView1.CellEndEdit
    2. DataGridView1.SuspendLayout()
    3. Dim CurrentCell = DataGridView1.CurrentCell
    4. Await Threading.Tasks.Task.Delay(1)
    5. DataGridView1.CurrentCell = CurrentCell
    6. DataGridView1.ResumeLayout()
    7. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Hi VaporiZed,

    ganz offensichtlich hast du die Problematik "auf deinem Schirm" ! Deine Lösung tut genau das, wonach ich gesucht hatte! Danke für diesen professionellen Ratschlag !

    Jetzt ist nur noch eins schade: dass ich dir nicht 10 x "hilfreich" geben kann. Na, vielleicht tun das ja andere für mich. :)

    Danke noch mal ... und einen schönen Tag an alle !

    LG
    Peter

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

    Öhm, ich versteh nicht ganz. Meine Lösung beinhaltet doch das bleib-bei-der-Zelle-Problem schon. Zu Beginn von CellEndEdit merkt sich die Variable die aktuelle Zelle. Und nach dem Await ändert sich die aktuelle Zelle, wird aber wieder auf die alte Zelle zurückgesetzt. Keine Zusatzvariable nötig. Oder ich hab das Rest-Problem nicht verstanden.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    War vielleicht ein bissl viel Text ... ich glaube, du hast etwas überlesen:

    Peter329 schrieb:

    off topic:


    Deine Lösung ist doch vollkommen in Ordnung ! Ich hab meinen erfolglosen Lösungsversuch nur deshalb eingestellt, um zu zeigen wie es eben NICHT funktioniert. Das führt offensichtlich eher zur Konfusion und deshalb habe ich den "off topic" Teil entfernt, um die Diskussion nicht in die Irre zu leiten !

    LG
    Peter

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