2009-02-25 7 views
2

ich eine benutzerdefinierte Kontrolle gemacht habe, ist es ein Flowlayoutpanel, in dem ich ein paar anderen benutzerdefinierten Steuerelemente setzte (nur Buttons, überschichtet mit jeweils drei Labels und ein PictureBox)extrem langsam C# benutzerdefinierte Steuerung

Es funktioniert ok mit ungefähr 100 Knöpfen, aber stoß das bis 1000 und es ist in Schwierigkeiten. Bump das bis zu 5000 und es stirbt nur nach 20 Sekunden.

Ich habe sehr wenig benutzerdefinierten Code, und ich verwende sinnvoll Suspend und Lebenslauf-Layout.

Also, was mache ich falsch? Ich bin mir sicher, dass mein (ziemlich schneller) Computer in der Lage sein sollte, ein paar tausend Knöpfe und Etiketten zu handhaben.

(Ich bin zu C# GUI Zeug ziemlich neu, so vielleicht soll ich die Dinge völlig anders sowieso tun.)

Edit 1:

Das ist so ziemlich der einzige zur Zeit benutzerdefinierte Code:

flowLayoutPanel1.SuspendLayout(); 
foreach (DataRow row in dt.Rows) // dt is from a DB query 
{ 
    flowLayoutPanel1.Controls.Add(new PersonButton(row)); 
} 
flowLayoutPanel1.ResumeLayout(); 

und im PersonButton Konstruktor:

this.label1.Text = row["FirstName"].ToString().Trim() + " " 
    + row["Surname"].ToString().Trim(); 

(Es sollte auch ein Bild angehängt sein, aber ich bin mir nicht sicher, ob jemand sie sehen können.)

Edit 2:

Ich denke, ich sollte wirklich ein Datagridview verwenden, oder Listview, aber ich wollte mehr als nur eine Textzeile und ein kleines Symbol pro Zeile; Ich wollte, dass es ähnlich der Download-Ansicht in Firefox aussieht (Strg + J). (Siehe Screenshot)

Vielen Dank für Ihre Eingabe, BTW. Ich denke, ich werde überdenken müssen ...

alt text http://img156.imageshack.us/img156/1057/capture.png

+0

Sind Sie sicher, dass dies ein benutzerdefiniertes Steuerelement ist und kein Benutzersteuerelement? Es hört sich so an, als hätten Sie eine Benutzerkontrolle vorgenommen. – recursive

+1

"Was mache ich falsch?" Anzeige von 1000 Schaltflächen in einem Formular. –

+0

Versuchen Sie das Seitennavigationskonzept zu verwenden –

Antwort

14

Kann eine C# WinForm-App 1000 Instanzen einer beliebigen Art von Steuerelement verarbeiten? Ich bin kein WinForm-Guru, aber was Sie von Ihrer Anwendung erwarten, könnte unangemessen sein.

Die Tatsache, dass Sie mehr als 1000 Steuerelemente eines beliebigen Typs anzeigen möchten, könnte ein Zeichen dafür sein, dass Sie das Design Ihrer Software aus der falschen Richtung betrachten.

+0

Ich war besorgt, dass die Antwort wäre :) – aidan

+2

Einverstanden! Warum sollten Sie 1000 Steuerelemente in einem Formular anzeigen? –

+0

+1 Matthew, wie kann ein Benutzer erwartet werden, 5000 verschiedene Tasten zu verfolgen? – scottm

2

Sie werden einige der Layout-Code schreiben müssen, oder wir helfen können, zu viel/gar nicht.

Auch Ihre Nr. 1 beste Wette ist, Ihren Code zu profilieren. Profiling ist der einzige todsichere Weg, herauszufinden, was genau in Ihrem Code langsam abläuft. Meiner Erfahrung nach gilt dies insbesondere für den UI-Code.

+0

Soll ich den Layoutcode hier in den Kommentaren posten? flowLayoutPanel1.SuspendLayout(); foreach (DataRow-Zeile in dt.Rows) { flowLayoutPanel1.Controls.Add (neuer PersonButton (Zeile)); } flowLayoutPanel1.ResumeLayout(); Das ist der einzige benutzerdefinierte Code. Außer dem PersonButton-Konstruktor, der die Beschriftungen ändert. – aidan

+0

Ich würde die Hauptfrage aktualisieren. – JaredPar

1

Bei 1000+ Schaltflächen läuft Ihr wahrscheinlich gefährlich wenig GDI-Ressourcen und/oder Raw-Handles für Ihre Anwendung.

Nicht sicher, was Ihre Anwendung tun soll, aber ein Gitter oder eine Combo-Box könnte hier die bessere Option sein.

1

Es klingt, als ob Sie ernsthaft Ihre Schnittstelle überdenken müssen.

Wie andere erwähnt haben, ist die Anzahl der Steuerelemente in einem Formular nicht verwendbar.

Allerdings habe ich einige Zeit damit verbracht, neue Steuerelemente im Code zu erstellen, sogar mit Reflektion, und festgestellt, dass mehrere Hundert datengebundene Steuerelemente, die in einem Flow-Layout-Bedienfeld erstellt wurden, in 1: 2 erstellt werden sollten Sekunden.

Das Posten von mehr Codebeispielen kann helfen, eine bessere Antwort zu erhalten.

Weitere Informationen: Ich habe gerade meinen Timing-Test erneut durchgeführt, 300 Kontrollen dauerte 0,5 Sekunden, 400 dauerte 1,9 Sekunden, 600 dauerte 3 Sekunden, 1000 dauerte 6 Sekunden.
Es scheint, dass es eine Grenze irgendwo zwischen 300 und 400 gibt, wo Ressourcen beginnen, übergenutzt zu werden.

1

Die Layout-Logik, die für 5k-Steuerelemente erforderlich ist, ist für jede Art von Umhüllungspanel zu viel. Vielleicht möchten Sie in eine andere Art von Steuerelement sehen, die Tausende von Einträgen halten - so etwas wie eine DataGridView.

Das DataGridView hat verschiedene zur Verfügung, die für die Art der Daten funktionieren soll, die Sie anzeigen (Bilder, Schaltflächen, Beschriftungen). Da Ihre Datenbankabfrage versucht, eine DataTable zurückzugeben, können Sie einfach bind that directly to your DataGridView und die Schleife entfernen.

0

[Necromantic mode = ON]

Sie haben 1000 Reihe von Daten, aber Sie können nur ein paar von ihnen zeigen, so schaffen nur die Steuerelemente, die sichtbar wird, und wieder verwenden sie ihren Inhalt mit dem neuen Wechsel Daten beim Scrollen.

-1

Versuchen Sie dies; Löschen Sie diese Methode in Ihrem Code.

protected override CreateParams CreateParams { erhalten { CreateParams cp = base.CreateParams; cp.ExStyle | = 0x02000000; Rückkehr cp; } }

+0

Sie sollten erklären, warum das funktionieren würde –