Entwickler-Ecke

WinForms - DataGridView selected row


Peter Bär - Fr 20.05.11 10:09
Titel: DataGridView selected row
Hallo

Ausgangslage:

1. DataGridView mit 100 Zeilen
2. Selektiere Zeile mit Maus (z.B. Zeile 7)
3. Ändere Zeilenselektion durch Code / Event KeyPress() auf Zeile 36
4. Nach Selektion mit Pfeiltaste auf Zeile 37 springen


Beispielcode zu Pos. 3
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
private void dataGridView6_KeyDown(object sender, KeyEventArgs e)
        {
            // Variablen erstellen
            int i_index = -1;
            // Pfeiltaste nach unten beachten
            if (e.KeyCode == Keys.Down)
            {
                // Selektion ermitteln
                foreach(DataGridViewRow _d_dgvr in dataGridView6.SelectedRows)
                {
                    // Index setzen
                    i_index = _d_dgvr.Index;

                    // Selektion loeschen
                    foreach (DataGridViewRow row in dataGridView6.SelectedRows)
                    {
                        row.Selected = false;
                    }

                }
                // Selektion setzen
                dataGridView6.Rows[i_index + 1].Selected = true;
                dataGridView6.FirstDisplayedScrollingRowIndex = dataGridView6.Rows[i_index + 1].Index;
           }
           else
           {
            }

}


Problem:
Wenn ich die Funktion mit der Pfeiltaste auslöse, wird die Zeile 37 selektiert und angezeigt (alles ok, getestet mit MessageBox).
Nach dem Beenden KeyPress-Ereignisses wird die Selektion wieder auf die Zeile 7 + 1 gesetzt, also auf Zeile 8.

Frage:
Warum bleibt die Selektion nicht auf der neu gesetzten Selektion bestehen?
Welcher Unterschied besteht bei einer codeselektierten Zeile und einer mausselektierten Zeile?
Gibt es eine Funktion die die Mausselektion übersteuert? (dataGridView6.ClearSelection(); funktioniert auch nicht)

Irgendwie hat die neu selektierte Zeile nicht die gleichen Eigenschaften wie eine selektierte Zeile mit der Maus.
Die neu selektierte Zeile wird also ignoriert oder überschrieben.

Hat jemand einen Tip?


Ralf Jansen - Fr 20.05.11 10:48

KeyDown findet sehr früh in der Eventfolge der Keybehandlung statt. Das Grid wird während dessen noch irgendetwas selber tun. Dein Code wäre wohl besser in KeyUp aufgehoben wenn es denn nicht die DataGridView.ProcessDataGridViewKey [http://msdn.microsoft.com/de-de/library/system.windows.forms.datagridview.processdatagridviewkey.aspx] Methode gäbe die für die Implementierung einer eigenen Navigation gedacht ist.


Peter Bär - Fr 20.05.11 11:29

Ich habe meinen Code in das KeyUp-Ereigniss eingefügt und hatte leider keinen Erfolg.
Die mausselektierte Zeile wird immer noch nachträglich selektiert.

Ich werde mich mal mit deiner vorgeschlagenen Methode auseinandersetzen um die Selektierung zu erzwingen.


Dr. Hallo - Fr 20.05.11 13:36

Du kannst womöglich auch OnKeyDown überschreiben und Handled auf true setzen...


C#-Quelltext
1:
2:
3:
4:
5:
6:
protected override void OnKeyDown(KeyEventArgs e)
{
    //machwas...
    e.Handled = true;
    base.OnKeyDown(e);
}


Peter Bär - Fr 20.05.11 14:14

Dein Vorschlag funktioniert perfekt.
Die gewünschte Zeile wird zum richtigen Zeitpunkt angezeigt und nicht mehr überschrieben.

Hier noch mein Beispielcode:

c# Beispielcode
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
private void dataGridView6_KeyDown(object sender, KeyEventArgs e)
        {
            // Pfeiltaste nach unten beachten
            if (e.KeyCode == Keys.Down)
            {
                //Handle ausloesen
                OnKeyDown(e);
            }

            else
            {
            }

        }
protected override void OnKeyDown(KeyEventArgs e)
        {
            // Variablen erstellen
            int i_index = -1;
            // Pfeiltaste nach unten beachten
            if (e.KeyCode == Keys.Down)
            {
                // Selektion ermitteln
                foreach (DataGridViewRow _d_dgvr in dataGridView6.SelectedRows)
                {
                    // Index setzen
                    i_index = _d_dgvr.Index;

                    // Selektion loeschen
                    foreach (DataGridViewRow row in dataGridView6.SelectedRows)
                    {
                        row.Selected = false;
                    }

                }
                // Selektion setzen
                dataGridView6.Rows[i_index + 1].Selected = true;
                dataGridView6.FirstDisplayedScrollingRowIndex = dataGridView6.Rows[i_index + 1].Index;
            }
            else
            {
            }

            // Handle setzen
            e.Handled = true;
            base.OnKeyDown(e);
        }


Vielen Dank für eure Hilfe.