Springen Sie in DataGridView bei KeyDown- oder PreviewKeyDown-Ereignissen um n Zeilen nach oben oder unten

Springen Sie in DataGridView bei KeyDown- oder PreviewKeyDown-Ereignissen um n Zeilen nach oben oder unten

Die Lösung für das Springen von n Zeilen nach oben oder unten in DataGridView bei KeyDown- oder PreviewKeyDown-Ereignissen
ist unten angegeben:

Ich habe Probleme bei der Implementierung der Pfeiltastennavigation einer DataGridView (keine Datenquelle verwendet).
Die DataGridView hat 2 verschiedene Arten von Elementen, meistens ist jedes zweite Element vom ersten Typ, umgekehrt sind die anderen vom zweiten Typ. Wenn jetzt jemand KeyUp / Down drückt, möchte ich, dass die DataGridView zu einer Zeile eines bestimmten Index springt, nicht zu einer nach oben oder unten.

Egal wie ich versuche, dies zu lösen, es ist nicht klar, wann das Ereignis tatsächlich endet. Wenn ich das in der _previewKeyDown-Methode versuche:

if (DgvCarPosAndTrafficMsg.CurrentRow != null)
        {
            if (e.KeyCode == Keys.Down)
            {
                if (DgvCarPosAndTrafficMsg.SortOrder == SortOrder.Ascending)
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i < SessionItems.Count; i++)
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i > 0; i--)
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
            }
            else if (e.KeyCode == Keys.Up)
            {

                if (DgvCarPosAndTrafficMsg.SortOrder == SortOrder.Descending)
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i < SessionItems.Count; i++)
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = DgvCarPosAndTrafficMsg.CurrentRow.Index; i > 0; i--)
                    {
                        if (SessionItems[i] is CarPosItem)
                        {
                            DgvCarPosAndTrafficMsg.Rows[i].Selected = true;
                            break;
                        }
                    }
                }
            }

es würde immer noch nur 1 Zeile nach oben oder unten springen.
Ich habe keine Ahnung, wann dieses Ereignis tatsächlich automatisch verarbeitet wird, und ich hätte gerne mein eigenes Verhalten von Key Up Down-Ereignissen. Bitte helfen Sie mir, DataGridViews in C# und ihre lästigen Ereignisse sind für mich sehr schwer aufzuspüren. Anscheinend wird jedes Event dieser Grids unterschiedlich verarbeitet, bei manchen Events wurde der neue Zustand bereits übernommen, bei anderen (OnSelectionChanged) wird er nachträglich verarbeitet. Es ist schlecht dokumentiert und nicht intuitiv, ich möchte all dieses Hintergrund-Zeug vermeiden/überschreiben.

Ok, ich habe eine Lösung gefunden, die nur eine Ereignismethode verwendet:

Hier ist mein Code, es ist wichtig, die evenArgs so einzustellen, wie sie behandelt werden, und dann Ihre eigene Update-Methode des Grids durchzuführen:

    private void DgvCarPosAndTrafficMsg_KeyDown(object sender, KeyEventArgs e)
    {
        int diffDown;
        int diffUp;
        if (DgvCarPosAndTrafficMsg.SortOrder == SortOrder.Descending)
        {

            diffDown = 1;
            diffUp = -2;
        }
        else
        {

            diffDown = 2;
            diffUp = -1;
        }

        if (DgvCarPosAndTrafficMsg.CurrentRow != null)
        {
            if (e.KeyCode == Keys.Down && DgvCarPosAndTrafficMsg.CurrentRow.Index < DgvCarPosAndTrafficMsg.Rows.Count - diffDown)
            {

                DgvCarPosAndTrafficMsg.CurrentCell = DgvCarPosAndTrafficMsg.Rows[DgvCarPosAndTrafficMsg.CurrentRow.Index + diffDown].Cells[0];
            }
            else if (e.KeyCode == Keys.Up && DgvCarPosAndTrafficMsg.CurrentRow.Index + diffUp > 0)
            {

                DgvCarPosAndTrafficMsg.CurrentCell = DgvCarPosAndTrafficMsg.Rows[DgvCarPosAndTrafficMsg.CurrentRow.Index + diffUp].Cells[0];
            }

        }
        e.Handled = true;
        DgvCarPosAndTrafficMsg_UpdateAll();
    }

Ich springe immer 2 Zeilen nach oben / unten, da ich dort das Element des gleichen Typs erwarte, aber in meiner UpdateAll () -Methode überprüfe ich erneut, ob es korrekt war, und korrigiere es bei Bedarf, andernfalls (falls bereits korrekt) aktualisiere ich die Visualisierung der Daten (und andere Raster mit Details des ausgewählten Eintrags füllen). Ich hoffe, dass dies auch anderen helfen wird.

Möglicherweise haben Sie für beide Ereignisse -2 und + 2, ich habe danach eine Behandlung, also sind diese Werte meine Indizes, die ich brauchte, passen Sie dies an Ihren Fall an oder geben Sie einen bestimmten Index an (wie in der Frage zu sehen)