Dies ist mein erstes Mal auf StackOverflow, so entschuldigen Sie die unordentliche Code-Formatierung unten.
Um zu verhindern, dass das Formular beim Aktualisieren der ListView gesperrt wird, können Sie die unten stehende Methode verwenden, um dieses Problem zu beheben.
Hinweis: Diese Methode sollte nicht verwendet werden, wenn Sie das ListView mit mehr als etwa 20.000 Elementen füllen möchten. Wenn Sie dem ListView mehr als 20.000 Elemente hinzufügen möchten, sollten Sie das ListView im virtuellen Modus ausführen.
Sie müssen kein IProgress-Objekt angeben, verwenden Sie einfach null, und die Methode funktioniert genauso gut.
Im Folgenden finden Sie ein Beispiel für die Verwendung der Methode.
Definieren Sie zuerst eine Klasse, die die Daten für das ListViewItem enthält.
public class TestListViewItemClass
{
public int TestInt { get; set; }
public string TestString { get; set; }
public DateTime TestDateTime { get; set; }
public TimeSpan TestTimeSpan { get; set; }
public decimal TestDecimal { get; set; }
}
Erstellen Sie dann eine Methode, die Ihre Datenelemente zurückgibt. Diese Methode kann eine Datenbank abfragen, eine Web-Service-API aufrufen oder was auch immer, solange sie eine IEnumerable Ihres Klassentyps zurückgibt.
Schließlich können Sie in dem Formular, in dem sich Ihre ListView befindet, die ListView auffüllen. Zu Demonstrationszwecken verwende ich das Load-Ereignis des Formulars, um das ListView aufzufüllen. Mehr als wahrscheinlich, möchten Sie dies an anderer Stelle auf dem Formular tun.
Ich habe die Funktion, die ein ListViewItem aus einer Instanz meiner Klasse, TestListViewItemClass generiert. In einem Produktionsszenario möchten Sie die Funktion wahrscheinlich anderswo definieren.
private async void TestListViewForm_Load(object sender, EventArgs e)
{
var function = new Func<TestListViewItemClass, ListViewItem>((TestListViewItemClass x) =>
{
var item = new ListViewItem();
if (x != null)
{
item.Text = x.TestString;
item.SubItems.Add(x.TestDecimal.ToString("F4"));
item.SubItems.Add(x.TestDateTime.ToString("G"));
item.SubItems.Add(x.TestTimeSpan.ToString());
item.SubItems.Add(x.TestInt.ToString());
item.Tag = x;
return item;
}
return null;
});
PopulateListView<TestListViewItemClass>(this.listView1, function, GetItems(), progress);
}
Im obigen Beispiel, habe ich ein IProgress Objekt im Konstruktor des Formulars wie folgt aus:
progress = new Progress<int>(value =>
{
toolStripProgressBar1.Visible = true;
if (value >= 100)
{
toolStripProgressBar1.Visible = false;
toolStripProgressBar1.Value = 0;
}
else if (value > 0)
{
toolStripProgressBar1.Value = value;
}
});
ich oft in Projekten dieser Methode zu bevölkern ein Listview verwendet haben, wo wir oben waren bevöl bis zu 12.000 Elemente in der ListView, und es ist extrem schnell. Die Hauptsache ist, dass Sie Ihr Objekt vollständig aus der Datenbank erstellen lassen müssen, bevor Sie das ListView für Aktualisierungen berühren.
Hoffentlich ist das hilfreich.
Ich habe unten eine asynchrone Version der Methode eingefügt, die die Hauptmethode aufruft, die oben in diesem Beitrag gezeigt wird.
public static Task PopulateListViewAsync<T>(ListView listView, Func<T, ListViewItem> func,
IEnumerable<T> objects, IProgress<int> progress) where T : class, new()
{
return Task.Run(() => PopulateListView<T>(listView, func, objects, progress));
}
Freeze bedeutet etwas anderes: es bedeutet, dass das Objekt (in diesem Fall eine Sammlung von Elementen) nicht ändert, während es eingefroren ist. In diesem Fall modifizierst du es sofort! –
Freeze war nur ein Begriff, den ich verwendet habe, um meine Anforderung zu erklären –