C# - Egyedi megjelenítésű ListBox

forráskód letöltése
Egy ListBox, vagy akár egy ComboBox elemeit nem csak a hagyományos módon jeleníthetjük meg, hanem arra is van lehetőségünk, hogy minden elemet mi magunk rajzoljunk ki, így akár minden elem más és más lehet, akár az aktuális értékétől függően, vagy bármi más feltételt figyelembe véve.
Ilyen esetben a ListBox DrawMode property-jének értékét OwnerDrawFixed vagy OwnerDrawVariable értékre válasszuk. Ekkor saját magunk rajzolhatjuk ki az elemeket. Ha minden elem egyforma magasságú, akkor használható az OwnerDrawFixed. Ha az elemek magassága változó, akkor ezt az OwnerDrawVariable érték és az IntegralHeight property hamisra állításával jelezhetjük. Ez esetben két eseményt kell felhasználnunk a megjelenítéshez. MeasureItem eseménynél kell megadnunk, hogy az adott elem milyen magas, míg a DrawItem eseménynél rajzolhatjuk meg azt.
Az "e" paraméter Index property-éből tudhatjuk meg, hogy hányadik az adott elem, melynek a magasságáról rendelkeznünk kell.
    private void listBox1_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e)
    {
      string s = listBox1.Items[e.Index].ToString();
      SizeF size = e.Graphics.MeasureString(s, new Font("Verdana", e.Index * 2 + 8));
Ezt az "e" paraméter ItemHeight property-jében adhatjuk meg.
      e.ItemHeight = (int)size.Height + 6;    
    }
Az elemek kirajzolásakor a DrawItem esemény kerül annyiszor meghívásra, ahány megjelenítendő elem van.
    private void listBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
    {
      Brush brush = new SolidBrush(Color.White);
Az alábbi vizsgálattal dönthetjük el, hogy az aktuálisan megjelenítendő elem kiválasztott-e a ListBox-ban vagy sem.
      if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
      {
Ha kiválasztott, akkor nem egy egyszerű fehér ecsetet használunk, hanem egy színátmeneteset.
        brush = new LinearGradientBrush(e.Bounds, Color.White, Color.Blue, 0.0);
      }      
Ezek után kirajzoljuk a hátteret, majd az adott elem szövegét és már készen is vagyunk.
      e.Graphics.FillRectangle(brush, e.Bounds);
      e.Graphics.DrawString(listBox1.Items[e.Index].ToString(), new Font("Verdana", e.Index * 2 + 8), new SolidBrush(Color.Black), new PointF(e.Bounds.X+3, e.Bounds.Y+3));
    }