Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Einige Fragen zum DataGridView

11 views
Skip to first unread message

Werner Perplies

unread,
May 31, 2008, 7:06:22 AM5/31/08
to
Hi,

ich bräuhe am wieder etwas Hilfe:

Ich habe einen DataGridView eine DataTable zugeordnet. Die Tabelle ist
durch Click auf die Kopfzeile sortierbar.

Ich würde beim Sortieren erwarten, dass die selektierte Zeile (Row) mit dem
Inhalt neu positioniert würde, dem ist bei mir aber nicht so, die Selektion
bleibt für die physikalische Zeile erhalten.

Also, wenn die Zeile vier selektiert war, ist auch nach der Sortierung die
Zeile vier selektiert, obwohl der Inhalt in eine andere Zeile gewandert
ist.
Ein ähnliches Problem habe ich nach dem Einfügen einer Zeile (add Row in
Datatable).

Die neue Zeile wird am Ende angezeigt, die vorherige Selektion ist aber
erhalten geblieben.

Ich (der User?) hätte erwartet, dass der neue Datensatz selektiert ist.

Wie selektiere ich gezielt eine Zeile im DataGridview?

Schon mal Danke ür die Hilfe.

Werner
--
www.weepee.eu

Frank Dzaebel

unread,
May 31, 2008, 9:05:01 AM5/31/08
to
Hallo Werner,

> Ich habe einen DataGridView eine DataTable zugeordnet. Die Tabelle ist
> durch Click auf die Kopfzeile sortierbar.
> Ich würde beim Sortieren erwarten, dass die selektierte Zeile (Row) mit
> dem
> Inhalt neu positioniert würde, dem ist bei mir aber nicht so, die
> Selektion
> bleibt für die physikalische Zeile erhalten.

ja, richtig.
Um das anzupassen gäbe es u.a. Möglichkeiten, wie diese:

[Gleicher Zeilen-Inhalt nach Sortieren beim DataGridView]
http://dzaebel.net/DataGridViewSort.htm

Um bei mehreren Zeilen die DataGridViewRow ggf.
sichtbar zu machen, kann man zusätzlich Dinge wie
FirstDisplayedCell benutzen:

[DataGridView.FirstDisplayedCell-Eigenschaft (System.Windows.Forms)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.datagridview.firstdisplayedcell.aspx


ciao Frank
--
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Werner Perplies

unread,
May 31, 2008, 9:28:27 AM5/31/08
to
Hallo Frank,

Am Sat, 31 May 2008 15:05:01 +0200 schrieb Frank Dzaebel:

> Hallo Werner,
>
>> Ich habe einen DataGridView eine DataTable zugeordnet. Die Tabelle ist
>> durch Click auf die Kopfzeile sortierbar.
>> Ich würde beim Sortieren erwarten, dass die selektierte Zeile (Row) mit
>> dem
>> Inhalt neu positioniert würde, dem ist bei mir aber nicht so, die
>> Selektion
>> bleibt für die physikalische Zeile erhalten.
>
> ja, richtig.

;-)
Kaum zu glauben, das das richtig sein soll, oder gibt es irgendeinen
tiefen, mir unbekannten Sinn, hinter diesem Verhalten?

> Um das anzupassen gäbe es u.a. Möglichkeiten, wie diese:
>
> [Gleicher Zeilen-Inhalt nach Sortieren beim DataGridView]
> http://dzaebel.net/DataGridViewSort.htm

Ja, das werde ich dann mal versuchen, nachzuvollziehen.

Da steckt vermutlich auch die Lösung drin, um die aktuelle Position einer
angefügten Zeile mit DataTable.Rows.Add() in einem sortierten DataGridView
zu ermitteln, oder?

Die naheliegende Verwendung von DataGridView.NewRowIndex funktioniert ja
leider nicht.

Danke

Gruß

Werner


>
>
>
> Um bei mehreren Zeilen die DataGridViewRow ggf.
> sichtbar zu machen, kann man zusätzlich Dinge wie
> FirstDisplayedCell benutzen:
>
> [DataGridView.FirstDisplayedCell-Eigenschaft (System.Windows.Forms)]
> http://msdn.microsoft.com/de-de/library/system.windows.forms.datagridview.firstdisplayedcell.aspx
>
>
> ciao Frank


Werner
--
www.weepee.eu

Werner Perplies

unread,
May 31, 2008, 10:57:17 AM5/31/08
to
Am Sat, 31 May 2008 15:05:01 +0200 schrieb Frank Dzaebel:


Werner
--
www.weepee.eu

Werner Perplies

unread,
May 31, 2008, 11:01:03 AM5/31/08
to
Hallo Frank,

Am Sat, 31 May 2008 15:05:01 +0200 schrieb Frank Dzaebel:

Verstanden habe ich es ja noch nicht so richtig, aber das Sortieren
funktioniert jetzt genau so, wie ich es erwarten würde.

Vielen Dank.

Jetzt werde ich mich mal an das Problem mit der hinzugefügten Zeile machen.

Gruß

Werner

Werner Perplies

unread,
May 31, 2008, 12:35:18 PM5/31/08
to
Hallo Frank,

Am Sat, 31 May 2008 15:05:01 +0200 schrieb Frank Dzaebel:

> Hallo Werner,
mit der hinzgefügten Zeile komme ich leider nicht weiter.

Vielleicht könntest Du mir ja noch einen Tipp geben.

In der DataTable steht der neue Datensatz auf jeden Fall am Ende.
Wie kann ich jetzt erreichen, das im DataGridView die Schreibmarke _und_
die Selektion genau auf diesen Datensatz positioniert wird. Die Position
ist natürlich abhängig von der aktuellen Sortierung.


Werner
--
www.weepee.eu

Frank Dzaebel

unread,
May 31, 2008, 12:46:42 PM5/31/08
to
Hallo Werner,

>>> ... Inhalt neu positioniert würde, dem ist bei mir aber nicht


>>> so, die Selektion bleibt für die physikalische Zeile erhalten.
>>
>> ja, richtig.
>
> ;-)
> Kaum zu glauben, das das richtig sein soll, oder gibt es irgendeinen
> tiefen, mir unbekannten Sinn, hinter diesem Verhalten?

"Richtig" von Dir geschildert war gemeint.
Allerdings erschliesst sich Dir, wenn Du einmal die Lösung
von mir ausprobiert hast, dass der User auch andere
Dinge erwartet. Etwa Dinge wie:
Die Zeile soll eigentlich auf der gleichen Position
(Höhe) bleiben, die Sortierung soll komlett umgekehrt
werden, der visuelle Effekt darf nicht so sein, dass
man gar nicht mehr weiss, wo man sich befindet,
er sollte also möglichst "smart" ablaufen.


> Da steckt vermutlich auch die Lösung drin, um die aktuelle Position einer
> angefügten Zeile mit DataTable.Rows.Add() in einem sortierten
> DataGridView zu ermitteln, oder?

Für das DataGridView gibt es zum Beispiel
ddgv.CurrentRow als Abfrage. Ansonsten normal
die "BindingSource.Position", die man abfragen
und setzen kann.

Frank Dzaebel

unread,
May 31, 2008, 1:03:48 PM5/31/08
to
Hallo Werner,

sry, das sollte gar nicht abgeschickt werden.
Ich habe weiter unten geantwortet.

Frank Dzaebel

unread,
May 31, 2008, 1:02:33 PM5/31/08
to
Hallo Werner,

> mit der hinzgefügten Zeile komme ich leider nicht weiter.
> Vielleicht könntest Du mir ja noch einen Tipp geben.

private void button1_Click(object sender, EventArgs e)
{
int lastRow = dgv.Rows.
GetLastRow(DataGridViewElementStates.Visible);
dgv.Rows[lastRow].Selected = true;
dgv.FirstDisplayedScrollingRowIndex = lastRow;

Werner Perplies

unread,
May 31, 2008, 1:26:04 PM5/31/08
to
Hallo Frank,

Am Sat, 31 May 2008 19:03:48 +0200 schrieb Frank Dzaebel:

> Hallo Werner,
>
> sry, das sollte gar nicht abgeschickt werden.
> Ich habe weiter unten geantwortet.
>

Schade, wo Du doch den berechtigten Einwand mit der Umkehr der Sortierfolge
hattest.

Da macht das Standardverhalten sicherlich Sinn, wenn die Schreibmarke am
Anfang oder am Ende steht.

Aber an deren Positionen? Da fehlt mir gerade noch die Fantasie für eine
sinnvolle Anwendung.

Gruß

Werner

Werner Perplies

unread,
May 31, 2008, 1:32:29 PM5/31/08
to
Frank,

Am Sat, 31 May 2008 19:02:33 +0200 schrieb Frank Dzaebel:

> Hallo Werner,
>
>> mit der hinzgefügten Zeile komme ich leider nicht weiter.
>> Vielleicht könntest Du mir ja noch einen Tipp geben.
>
> private void button1_Click(object sender, EventArgs e)
> {
> int lastRow = dgv.Rows.
> GetLastRow(DataGridViewElementStates.Visible);
> dgv.Rows[lastRow].Selected = true;
> dgv.FirstDisplayedScrollingRowIndex = lastRow;
> }
>
>
> ciao Frank

Vielleicht habe ich mich unverständlich ausgedrückt, stell Dir bitte
folgendes vor:
Liste (sortiert):
A
B
D
> E Schreibmarke und Selektion
F

In DataTable (DataSource)
dt.Rows.Add(row) // row enthält C;

Danach sieht die Liste so aus:

A
B
C
D
>E Schreibmarke und Selektion
F

Ich möchte aber folgendes haben:

A
B
> C Schreibmarke und Selektion
D
E
F

Alles klar?

Danke für Deine Mitarbeit.

Gruß

Werner
--
www.weepee.eu

Frank Dzaebel

unread,
May 31, 2008, 2:00:14 PM5/31/08
to
Hallo Werner,

> [...] Einfügen der Row "C".


> Ich möchte aber folgendes haben:
> A
> B
>> C Schreibmarke und Selektion
> D

Du willst also eigentlich nur die Zeile C selektieren.
(so interpretiere ich das jetzt).

Dann kennst Du den Wert der PK-Spalte der Row
(C) die Du selektieren willst - ich nenne ihn "idWert".
Dann nutze folgende Methode:

int positionID = personBindingSource.Find("ID", idWert);
personBindingSource.Position = positionID;

Frank Dzaebel

unread,
May 31, 2008, 2:55:41 PM5/31/08
to
Hallo Werner,

>> Ich habe weiter unten geantwortet.
>>
> Schade, wo Du doch den berechtigten Einwand
> mit der Umkehr der Sortierfolge hattest.
> Da macht das Standardverhalten sicherlich Sinn, wenn
> die Schreibmarke am Anfang oder am Ende steht.

ja, wie gesagt, Deine Frage ist auch nicht unbegründet
und deswegen habe ich ja auch den Artikel mit einem
Lösungsansatz geschrieben.


> Aber an deren Positionen? Da fehlt mir gerade noch
> die Fantasie für eine sinnvolle Anwendung.

Ich weiss gerade nicht, was mit "deren Positionen"
detailliert gemeint ist. Lass uns einfach unten im Thread
weiterdiskutieren, denn dort sind Vorschläge
für die Positionierung gepostet, wenn PK-Werte
bekannt sind.

Werner Perplies

unread,
Jun 1, 2008, 1:02:44 AM6/1/08
to
Hallo Frank,

Am Sat, 31 May 2008 20:00:14 +0200 schrieb Frank Dzaebel:

> Hallo Werner,
>
>> [...] Einfügen der Row "C".
>> Ich möchte aber folgendes haben:
>> A
>> B
>>> C Schreibmarke und Selektion
>> D
>
> Du willst also eigentlich nur die Zeile C selektieren.
> (so interpretiere ich das jetzt).
>
> Dann kennst Du den Wert der PK-Spalte der Row
> (C) die Du selektieren willst - ich nenne ihn "idWert".
> Dann nutze folgende Methode:
>
> int positionID = personBindingSource.Find("ID", idWert);
> personBindingSource.Position = positionID;

Vielen Dank.

Jetzt nähern wir uns der Sache, positionID enthält die _richtige_ Position.
Leider klappt nicht mit dem Setzen der Schreibmarke und der Selektion.

Zwar kann ich die richtige Selektion mit
dgv.Rows[positionID].Selected = true;
vornehmen, aber das versetzt nicht die Schreibmarke.

Irgenndwie scheint die Zeile
personBindingSource.Position = positionID
keine _sichtbare_ Auswirkung zu haben.

Vielleicht fehlt ja irgenwo ein Refresh, Repaint, Reset o. ä.

nur wo?

Werner Perplies

unread,
Jun 1, 2008, 2:20:07 AM6/1/08
to
Hallo Frank,

Am Sat, 31 May 2008 20:00:14 +0200 schrieb Frank Dzaebel:

Du hast mich auf den richtigen Weg geführt.

Ich hatte Anfangs in etwa Folgendes gemacht:

DatGridView dgv im Designer erstellt.

dann im Code:

Datatable -> dt
dgv.Datasource = dt;

New row erzeugt.

dann
dt.Add(row);

Danach wurde alles angezeigt, aber die neue Zeile nicht selektiert.

Nach dem Du mich auf

BindingSource.Find hingewiesen hast, habe ich die folgende BindingSource
erstellt:

BindingSource bs = new BindingSource(gdv.DataSource, gdv.DataMember);

Im Ergebnis funktionierte jetzt das Find, aber das Setzen der Position
hatte nicht die gewünschte Wirkung.

Zuletzt habe ich aus einem Beispiel von Microsoft Folgendes übernommen:

DataView dv = new DataView(dt);
BindingSource bds = new BindingSource();
bds.DataSource = dv;
dgv.DataSource = bds;

Jetzt reicht ein einfaches
dt.Add(row);
um den gewünschten Effekt zu erreichen.

Find ubd Position setzen sind also überflüssig.

Verstanden habe ich das alles noch nicht, aber ich arbeite dran. ;-)

DataView -> BindingSource -> BindingSource.DataSource -> dgv.DataSource
ist schon eine recht komplexe Voraussetzung.

Noch einmal vielen Dank für Deine Mithilfe.

Gruß
Werner
--
www.weepee.eu

Frank Dzaebel

unread,
Jun 1, 2008, 3:54:53 AM6/1/08
to
Hallo Werner,

> Du hast mich auf den richtigen Weg geführt.

schön, wenn es jetzt klappt.

> Im Ergebnis funktionierte jetzt das Find, aber
> das Setzen der Position hatte nicht die gewünschte Wirkung.

Das Setzen der BindingSource.Position hätte z.B. dann
nicht die gewünschte Wirkung, wenn die Position
schon auf diese gesetzt wurde. Was dann ggf. fehlt, ist
ein Setzen wie etwa hier (unten) über den
erwähnten FirstDisplayedScrollingRowIndex :

[Gleicher Zeilen-Inhalt nach Sortieren beim DataGridView]
http://dzaebel.net/DataGridViewSort.htm

> DataView dv = new DataView(dt);
> BindingSource bds = new BindingSource();

So eine Bindung ist eher seltener.
Häufiger findet die Bindung direkter über den
"bds.DataSource = dt;" statt. Das ist auch das
Szenario, über das ich hier gesprochen habe.

> Noch einmal vielen Dank für Deine Mithilfe.

gerne.

Werner Perplies

unread,
Jun 1, 2008, 7:09:53 AM6/1/08
to
Hallo Frank

Am Sun, 1 Jun 2008 09:54:53 +0200 schrieb Frank Dzaebel:

[...]

> So eine Bindung ist eher seltener.

;-)
nett, was wird damit bezweckt?


> Häufiger findet die Bindung direkter über den
> "bds.DataSource = dt;" statt.

Ich habe das gerade probiert, so funktioniert es auch!

> Das ist auch das
> Szenario, über das ich hier gesprochen habe.
>
>
>
>> Noch einmal vielen Dank für Deine Mithilfe.
>
> gerne.
>
>
> ciao Frank

Gruß
Werner
--
www.weepee.eu

Frank Dzaebel

unread,
Jun 1, 2008, 8:10:18 AM6/1/08
to
Hallo Werner,

>>> DataView dv = new DataView(dt);
>>> BindingSource bds = new BindingSource();
>>

>> So eine Bindung ist eher seltener.
>
> ;-)
> nett, was wird damit bezweckt?

Mit einem DataView kannst Du auf
Vorteile-Seite z.B. leichter filtern. Etwa:

[DataView.RowFilter-Eigenschaft (System.Data)]
http://msdn.microsoft.com/de-de/library/system.data.dataview.rowfilter(vs.80).aspx

Auf der Nachteile-Seite sind die Bezüge zur
Original-Datenquelle schwieriger, da normal
immer erst über ID (PK) der entsprechende
Datensatz gesucht werden muss.


>> Häufiger findet die Bindung direkter über den
>> "bds.DataSource = dt;" statt.
>
> Ich habe das gerade probiert, so funktioniert es auch!

Ja, wäge die oben genannten Vor- und Nachteile
gegeneinander ab.

0 new messages