Icons in einer ListView mit mehr Farben

Keine Zeit? Hier die Kurzversion in 30 Sekunden.
- Eine ImageList hat standardmäßig nur 8 Bit Farbtiefe, die Icons sehen nach 256 Farben aus.
- Mit
ColorDepth.Depth16Bitklappt es besser,Depth32Bitist für Icons mit Alphakanal die bessere Wahl.ColorDepthundImageSizemüssen vor dem Hinzufügen der Bilder gesetzt werden, sonst gehen sie verloren.- Die ListView in der Ansicht
LargeIconzeigt auch Bilder bis 256×256, zum Beispiel für eine Vorschau.- Mit zwei großen Buttons links und rechts wird daraus eine kleine Bildernavigation.
Ihr packt Bilder oder Icons in eine ListView und wundert euch, warum alles aussieht wie aus einem alten Katalog mit 256 Farben? Mir ist das auch passiert. Schuld ist nicht die ListView, sondern die ImageList dahinter.
Das Problem: 8 Bit Farbtiefe
Eine neue ImageList hat standardmäßig ColorDepth.Depth8Bit. Egal wie schön euer Bild ist, es wird auf 256 Farben gedrückt. Verläufe sehen dann körnig aus, Fotos erst recht.
Die Lösung ist simpel: Farbtiefe erhöhen. Ich hatte zuerst Depth16Bit genommen, dazu eine Bildgröße von 160 x 120. Das sieht schon deutlich besser aus. Wer aber Icons mit Alphakanal hat, also weichen Kanten und Halbtransparenz, nimmt besser Depth32Bit. Sonst bekommen die Ränder hässliche Treppen.
ImageList bilder = new ImageList();
bilder.ColorDepth = ColorDepth.Depth32Bit;
bilder.ImageSize = new Size(160, 120);Die höhere Farbtiefe kostet etwas mehr Speicher, bei ein paar Vorschaubildern merkt man das aber nicht.
Die ListView kann übrigens viel mehr, als man erwartet. Auch große Bilder sind kein Problem, die ImageSize darf bis zu 256 x 256 Pixel gehen. Perfekt für eine kleine Bildervorschau!
Die Reihenfolge ist wichtig
Hier stolpert man gern: ColorDepth und ImageSize müsst ihr setzen, bevor ihr Bilder hinzufügt. Ändert ihr eine der beiden Eigenschaften später, verwirft die ImageList die Bilder, die schon drin sind. Dann bleibt die Liste einfach leer und man sucht sich dumm.
Außerdem gilt: Die Bilder werden beim Hinzufügen auf die ImageSize skaliert. Passt also lieber gleich das Seitenverhältnis.
Das komplette Beispiel
Hier ein vollständiges Formular mit .NET 3.5 und C# 3.0. Die Bilder bekommen einen Schlüssel, über den die Einträge der ListView sie später wiederfinden. Die Pfade müsst ihr natürlich anpassen.
using System.Drawing;
using System.Windows.Forms;
public partial class MainForm : Form
{
private ImageList bilder = new ImageList();
private ListView vorschau = new ListView();
private Button zurueck = new Button();
private Button weiter = new Button();
public MainForm()
{
InitializeComponent();
// Erst Farbtiefe und Größe, dann die Bilder
bilder.ColorDepth = ColorDepth.Depth32Bit;
bilder.ImageSize = new Size(160, 120);
bilder.Images.Add("strand", Image.FromFile(@"C:\Bilder\strand.png"));
bilder.Images.Add("berge", Image.FromFile(@"C:\Bilder\berge.png"));
vorschau.View = View.LargeIcon;
vorschau.LargeImageList = bilder;
vorschau.Dock = DockStyle.Fill;
vorschau.BorderStyle = BorderStyle.None;
vorschau.BackColor = this.BackColor;
vorschau.Items.Add(new ListViewItem("Strand", "strand"));
vorschau.Items.Add(new ListViewItem("Berge", "berge"));
zurueck.Text = "<";
zurueck.Dock = DockStyle.Left;
zurueck.Width = 40;
weiter.Text = ">";
weiter.Dock = DockStyle.Right;
weiter.Width = 40;
// Das Fill-Control zuerst hinzufügen
Controls.Add(vorschau);
Controls.Add(zurueck);
Controls.Add(weiter);
}
}Ein paar Anmerkungen dazu. Mit Images.Add(key, image) vergebt ihr den Namen, und das ListViewItem greift über den ImageKey darauf zu, ohne dass ihr Indizes zählen müsst. Mit View.LargeIcon zeigt die ListView die großen Bilder an. Die Beschriftung steht dann darunter.
Eine kleine Bildervorschau
Jetzt noch die Idee, die ich ursprünglich im Kopf hatte: Links und rechts jeweils ein großer Navigationsbutton, dazwischen die ListView. Gebt der ListView dieselbe Hintergrundfarbe wie dem Formular und nehmt den Rahmen weg, dann wirkt alles aus einem Guss. Das Ganze hat dann wirklich Hand und Fuß.
Was die Buttons tun, bleibt euch überlassen. Ich würde mit EnsureVisible an der Liste arbeiten, damit der gewünschte Eintrag in den sichtbaren Bereich scrollt.
Habt ihr eure Icons in der ListView schon mal hübscher bekommen? Oder nutzt ihr was ganz anderes für Vorschaubilder? Schreibt es mir in die Kommentare!
Beitragsbild: eigene Collage mit Logo von Wikimedia Commons (.NET-Logo (2002): Microsoft), gemeinfrei; die Marke gehört ihrem Inhaber.
Christian Ackermann
Softwareentwickler (C++, C, Java, C#) aus der Oberpfalz, bloggt seit 2001 über Linux, Technik und Kochen.