Default-Implementierung für ListView OwnerDraw
Ich habe eine ListView, wo ich wünschte zu zwicken die Zeichnung der Elemente (zum Beispiel die Hervorhebung bestimmter Zeichenfolgen in der Listenansicht itmes), aber ich will nicht zu radikal verändern die Art und Weise, dass Gegenstände angezeigt werden.
Ich habe den OwnerDraw auf true und kann meinen Kopf herum, wie zu zeichnen, meine Hervorhebung Wirkung, aber immer wenn ich versuche zu verschieben, um die default-Implementierung zu ziehen, der rest der Liste Ansicht die Dinge schief gehen und ich bin Links mit eine ganze Menge von grafischen Problemen, die angibt, dass tatsächlich habe ich komplett schief gegangen ist.
Gibt es irgendwo, dass ich sehen kann, was der "Standard" - Handler für die DrawItem -
und DrawSubItem
events zu tun, so dass ich besser mein Verständnis und mehr leicht zwicken meinem code?
Zur Referenz hier ein Codeausschnitt, der zeigt, was ich bin derzeit dabei:
public MyListView()
{
this.OwnerDraw = true;
this.DoubleBuffered = true;
this.DrawColumnHeader += new DrawListViewColumnHeaderEventHandler(MyListView_DrawColumnHeader);
this.DrawItem += new DrawListViewItemEventHandler(MyListView_DrawItem);
this.DrawSubItem += new DrawListViewSubItemEventHandler(MyListView_DrawSubItem);
}
private void MyListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
//Not interested in changing the way columns are drawn - this works fine
e.DrawDefault = true;
}
private void MyListView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
}
private void MyListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
string searchTerm = "Term";
int index = e.SubItem.Text.IndexOf(searchTerm);
if (index >= 0)
{
string sBefore = e.SubItem.Text.Substring(0, index);
Size bounds = new Size(e.Bounds.Width, e.Bounds.Height);
Size s1 = TextRenderer.MeasureText(e.Graphics, sBefore, this.Font, bounds);
Size s2 = TextRenderer.MeasureText(e.Graphics, searchTerm, this.Font, bounds);
Rectangle rect = new Rectangle(e.Bounds.X + s1.Width, e.Bounds.Y, s2.Width, e.Bounds.Height);
e.Graphics.FillRectangle(new SolidBrush(Color.Yellow), rect);
}
e.DrawText();
}
- Ich denke, benötigen Sie mehr Informationen über das, was schief läuft. Getestet habe ich den code und es war...ok. Es markiert das Wort "Begriff" mit einer gelben box. Vielleicht zeigen Sie ein Bild von der Zeichnung Ergebnisse.
- Ich bekomme ein breites Spektrum von Themen, angefangen von der Auswahl Effekt nicht mehr sichtbar ist (was gesehen werden kann in dem obigen Beispiel) zu item-text "Doppel-gerendert" und auch verschwindet, wenn ich mit der Maus über das Element. Ich bin mir nicht erwarten, dass jemand in der Lage, auf Magische Weise lösen alle diese Probleme (das wäre auch viel zu spezifisch, um zu helfen, zukünftige Nutzer), sondern ich würde gerne sehen, ein Beispiel für die Implementierung, das macht alles so eng wie möglich an die standard-Implementierung
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich noch nicht die Zeit, jetzt zu schreiben, bis eine vollständige Antwort, so dass stattdessen werde ich einige schnelle Notizen und kommen später zurück.
Als LarsTech sagte, Besitzer Zeichnung ein
ListView
Kontrolle wird ein Schmerz - den .NetListView
- Klasse ist ein wrapper um die zugrunde liegenden Win32 Listenansicht-Steuerelement und die Fähigkeit, "Owner-draw" wird durch dieNM_CUSTOMDRAW
Benachrichtigung-code. Als solche gibt es keine "Standard .Net-Implementierung" - in der Standardeinstellung die zugrunde liegende Win32-control.Machen das Leben noch schwieriger, es gibt eine Reihe von zusätzlichen überlegungen zu machen:
DrawItem
undDrawSubItem
Sie kann gut sein, zeichnen Sie den Inhalt der ersten Zelle zweimal.DrawItem
Ereignis eintreten wird ohne entsprechendeDrawSubItem
Veranstaltungen, was bedeutet, dass, wenn Sie zeichnen Sie einen hintergrund in derDrawItem
Ereignis und ziehen Sie dann den text in dieDrawSubItem
Fall, dass Ihr Einzelteil-text verschwindet, wenn Sie mit der Maus über.ItemState
Eigenschaft ist nicht immer korrekt, zum Beispiel nur nach ändern der Größe einer Spalte. Daher habe ich gefunden, ist es am besten nicht auf Sie verlassen.DrawItem
Ereignis zuerst Eintritt, alles, was Sie zeichnen, in derDrawItem
- handler (z.B. die Auswahl Effekt), können auch überlagert werden durch Dinge, die Sie tun, in derDrawSubItem
- handler (z.B. dass bestimmte Zellen eine andere Hintergrundfarbe).Alles in allem ist die Handhabung Besitzer Zeichnung ist ein relativ aufwändiger Affäre - ich fand es am besten zu handhaben alle Zeichnung innerhalb der
DrawSubItem
Ereignis, es ist auch am besten führen Sie Ihre eigene double-buffering mithilfe desBufferedGraphics
Klasse.Ich fand auch Sie sich den Quellcode für ObjectListView sehr praktisch.
Schließlich, all dies ist nur um die details kümmern-Modus der Listenansicht (der einzige Modus den ich benutze), wenn Sie wollen, dass die anderen Modi zu arbeiten, dann glaube ich, dass es zusätzliche Dinge zu berücksichtigen.
Wenn ich die chance bekomme, werde ich versuchen und nach meinem Beispiel-code.
Ich weiß nicht, ob diese vollständig helfen, aber ich werde noch ein paar Hinweise:
Eine Sache im Auge zu behalten ist, dass
DrawSubItem
ziehen wird, das erste Element zu, und das ist wohl immer, wo Sie diedouble-rendered
Blick aus.Einige Dinge, um zu versuchen (nicht berücksichtigt für die Geschwindigkeit):
Für Ihre DrawSubItem routine, stellen Sie sicher, Sie sind nicht der Zeichnung in der ersten Spalte und ich fügte hinzu, die
DrawBackground()
routine. Ich fügte hinzu, einige clipping, um das Rechteck markieren, so dass Sie nicht malen Sie außerhalb der Spalte Parameter.Im Allgemeinen, Eigentümer zeichnen Sie ein ListView-Steuerelement willkommen in einer Welt voller Schmerzen. Sie sind nicht die Zeichnung in der Visuellen Styles mehr, Sie hätte zu tun, dass Sie sich, auch. Ugh.
Element ausgewählt werden, wieder die Farbe geändert. Standardmäßig blau in windows. Dieser code wird Ihnen helfen, für u in allen möglichen Farben:
ComponentOwl vor kurzem einen freeware-Komponente namens " Better ListView-Express.
Es sieht aus und verhält sich genau wie die ListView, hat aber viel mächtiger Eigentümer Zeichnung Fähigkeiten - Sie zeichnen können genau über alle Elemente und auch schalten Sie einige Zeichnung (z.B. Auswahl, um Sie auf).