Frage

Ich habe eine Listenansicht, die ich mit 8 Spalten von Benutzerdaten bin bevölkern. Der Benutzer hat die Möglichkeit, Auto erfrischend zu ermöglichen, die das Listview führt mit den neuesten Daten aus der Datenbank gelöscht und neu besiedelt werden.

Das Problem ist, dass, wenn die Elemente gelöscht und neu besiedelt, der sichtbare Bereich an die Spitze der Liste springt zurück. Also, wenn ich auf Artikel 1000 von 2000 suche, ist es sehr unbequem zu diesem Artikel zurück zu erhalten.

Im Grunde, was ich frage ist, wie kann ich die aktuellen Scroll-Abstände (x und y) erhalten und sie dann wieder her?

War es hilfreich?

Lösung

Ich hatte das gleiche Problem mit einer Weile her und ich landete einen Algorithmus zur Durchführung des Modell mit der Liste zu vergleichen, so dass ich nur / entfernte Elemente hinzugefügt, geändert hatte. Auf diese Weise, wenn es keine massiven Veränderungen waren, sahen die Liste nicht an den Anfang springen. Und die Hauptsache ich war es, die Effizienz erreichen wollte (so, dass die Liste nicht blinkt).

Andere Tipps

Ich wollte nur für diejenigen, einige Informationen zur Verfügung zu stellen, die verzweifelt versuchen, den Buggy ListView.TopItem Eigenschaft zu verwenden:

  1. Sie MÜSSEN die TopItem Eigenschaft nach dem Aufruf ListView.EndUpdate gesetzt
  2. Die Elemente der Listview-Kontrolle müssen ihre Eigenschaft Text auf etwas anderes festgelegt haben als String.Empty, oder arbeiten die Eigenschaft nicht.
  3. die ListView.TopItem Einstellung wirft NULL-Verweis Ausnahmen intermittierend. Halten Sie diese Codezeile innerhalb eines Try ... Catch-Block.

Natürlich ist dies bewirkt, dass die Scrollbar des Listview auf 0 springen und zurück in die Position des Top-Artikel, was ärgerlich ist. Bitte aktualisieren Sie diese Frage, wenn Sie eine Abhilfe für dieses Problem zu finden.

Ich habe folgende erfolgreich:

int topItemIndex = 0;
try
{
     topItemIndex = listView1.TopItem.Index;
}
catch (Exception ex)
{ }
listView1.BeginUpdate();
listView1.Items.Clear();
//CODE TO FILL LISTVIEW GOES HERE
listView1.EndUpdate();
try 
{ 
    listView1.TopItem = listView1.Items[topItemIndex];
}
catch (Exception ex)
{ }

Die TopItemIndex Eigenschaft auf Listview ist das, was Sie suchen, aber es hat einige Fehler bestätigt, die in VS2010 Version behoben werden sollten .. nicht sicher (nicht geprüft).

Wie auch immer, meine Abhilfe dieser Arbeit für die Herstellung ist, dies zu tun:

listViewOutput.TopItemIndex = outputList.Count - 1;
listViewOutput.TopItemIndex = myNewTopItemIndex;

Aus irgendeinem Grunde es direkt Einstellung es nicht aktualisiert, sondern es zum letzten Punkt einstellen und dann die, die ich zuverlässig funktioniert für mich will.

Schauen Sie sich die ListView.TopItem Eigenschaft. Es verfügt über einen Index, der seine Position in der Liste enthalten. Finden Sie, dass Index in der neuen Liste, und stellen Sie TopItem zu diesem Artikel, und es sollte automatisch das Scrollen tun.

Leider müssen Sie einige Interop verwenden, um die genaue Position im Listview zu blättern. Verwenden Sie GetScrollInfo winapi Funktion die vorhandene Bildlaufposition zu erhalten und Sendmessage in die Position zu bewegen.

Es in einem Artikel über Codeproject namens Blättern zu einer Gruppe mit einem Listview das könnte man zu der Lösung führen.

Meine Lösung zur Aufrechterhaltung Scroll-Position:

Formularebene Variable:

private static int scrollSpot = 0;

Innerhalb Listview Refresh (dh Timer, Taste), um den aktuellen Ort zu speichern:

scrollSpot = this.listView1.TopItem.Index;
refreshTheForm();

Innerhalb refreshTheForm Methode der gespeicherten Stelle zu zeigen (bei sehr Ende Methode setzen):

if (scrollSpot <= 1)
{
     listView1.Items[scrollSpot].Selected = true;
}
else
{
     listView1.Items[scrollSpot - 2].Selected = true;
}
listView1.TopItem = listView1.SelectedItems[0]; 

Ich war mit sorten des gleichen Problems. Ich habe eine Listview, die ich all 1/2 sec bevölkern und wenn ich den TopItem zu einem ListItem, dessen Index> sichtbare Elemente gesetzt, dann ist die Liste sprang zwischen dem TopItem und wieder 2 Punkten.

Also, das Problem zu beheben, habe ich die TopIterm nach dem Aufruf von EndUpdate.

lvB.EndUpdate();
lvI.EndUpdate();
lvR.EndUpdate();

if (lstEntryInts.Items.Count > 0)
    lstEntryInts.TopItem = lstEntryInts.Items[iTopVisIdx];
if (lstEntryBools.Items.Count > 0)
    lstEntryBools.TopItem = lstEntryBools.Items[iTopVisIdx];
if (lstEntryReals.Items.Count > 0)
    lstEntryReals.TopItem = lstEntryReals.Items[iTopVisIdx];​

In meinen Tests, Sie brauchte nicht einmal die TopItem, obwohl ich ein int verwendet, um das ausgewählte Element zu speichern. Auch TopItem löst eine Ausnahme aus, wenn Sie View.Tile oder View.LargeIcon verwenden.

Dieser Code nicht die Bildlaufleisten bewegen:

listView1.BeginUpdate();
listView1.Items.Clear();

// loop through your add routine
listView1.Items.Add(lvi);

listView1.EndUpdate();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top