vbAccelerator - Contents of code file: IconEx\IconExListBox.cs

using System;
using System.Drawing;
using System.Windows.Forms;

using vbAccelerator.Components.Win32;

namespace vbAccelerator.Components.ListBox
{
   /// <summary>
   /// Listbox which displays a collection of IconEx objects
   /// </summary>
   public class IconExListBox : System.Windows.Forms.ListBox
   {
      #region Private Variables
      private IconEx iconEx = null;
      private int lastWidth = 0;
      #endregion

      #region Properties
      public vbAccelerator.Components.Win32.IconEx IconEx
      {
         get
         {
            return this.iconEx;
         }
         set
         {
            this.iconEx = value;
            addDeviceImages();
         }
      }
      #endregion

      #region Internal Implementation
      private void addDeviceImages()
      {
         this.Items.Clear();
         if (this.iconEx != null)
         {
            foreach (IconDeviceImage idi in this.iconEx.Items)
            {
               this.Items.Add(idi);
            }
         }
      }

      protected virtual string IconText(
         IconDeviceImage idi
         )
      {
         string colorDepth = "";
         switch (idi.ColorDepth)
         {
            case ColorDepth.Depth4Bit:
               colorDepth = "4 Bit";
               break;
            case ColorDepth.Depth8Bit:
               colorDepth = "8 Bit";
               break;
            case ColorDepth.Depth24Bit:
               colorDepth = "24 Bit";
               break;
            case ColorDepth.Depth16Bit:
               colorDepth = "16 Bit";
               break;
            case ColorDepth.Depth32Bit:
               colorDepth = "32 Bit";
               break;
         }
         string text = String.Format(
               "{0} x {1}, {2}",
               idi.IconSize.Width,
               idi.IconSize.Height,
               colorDepth);            
         return text;
      }

      protected override void OnDrawItem(DrawItemEventArgs e)
      {
         if ((e.Index > -1) && (e.Index < this.Items.Count))
         {
            IconDeviceImage idi = (IconDeviceImage)this.Items[e.Index];

            Bitmap bmOffscreen = new Bitmap(
               e.Bounds.Width,
               e.Bounds.Height);
            System.Drawing.Graphics gfx =
             System.Drawing.Graphics.FromImage(bmOffscreen);
            Rectangle bounds = new Rectangle(
               0, 0, e.Bounds.Width, e.Bounds.Height);

            // Draw background
            bool selected = ((e.State & DrawItemState.Selected) ==
             DrawItemState.Selected);
            if (selected)
            {
               gfx.FillRectangle(SystemBrushes.Highlight, bounds);
            }
            else
            {
               gfx.FillRectangle(SystemBrushes.Window, bounds);
            }

            // Draw the text:
            Brush brText = SystemBrushes.WindowText;
            if (selected)
            {
               brText = SystemBrushes.HighlightText;
            }
            StringFormat textFormat = new StringFormat();
            textFormat.Alignment = StringAlignment.Center;
            textFormat.Trimming = StringTrimming.EllipsisCharacter;
            textFormat.FormatFlags = StringFormatFlags.LineLimit;
            RectangleF textRect = new RectangleF(
               0, 
               (float)(idi.IconSize.Height + 2), 
               (float)bounds.Width, 
               (float)(bounds.Height - idi.IconSize.Height - 2)
               );
            gfx.DrawString(
               IconText(idi),
               this.Font,
               brText,
               textRect,
               textFormat);
            textFormat.Dispose();

            e.Graphics.DrawImageUnscaled(
               bmOffscreen, e.Bounds.X, e.Bounds.Y);

            // Draw the icon last (otherwise we lose alpha);
            e.Graphics.DrawIcon(idi.Icon, 
               e.Bounds.Left + (bounds.Width - idi.IconSize.Width) / 2,
               e.Bounds.Top + 2);

            gfx.Dispose();
            bmOffscreen.Dispose();
         }
         else
         {
            base.OnDrawItem(e);
         }
      }

      protected override void OnMeasureItem(MeasureItemEventArgs e)
      {
         if ((e.Index > -1) && (e.Index < this.Items.Count))
         {
            IconDeviceImage idi = (IconDeviceImage)this.Items[e.Index];
            string text = IconText(idi);
            SizeF textSize = e.Graphics.MeasureString(text, this.Font);
            e.ItemHeight = idi.IconSize.Height + (int)textSize.Height + 4;
            e.ItemWidth = Math.Max(
               idi.IconSize.Width,
               (int)textSize.Width);
         }
         else
         {
            base.OnMeasureItem(e);
         }
      }

      protected override void OnResize(EventArgs e)
      {
         if (this.Width != lastWidth)
         {
            // It is necessary to force a refresh
            // to ensure the items are centered.
            // ListBox assumes that items are aligned
            // Left or Right.
            this.Invalidate();
            lastWidth = this.Width;
         }
         base.OnResize(e);
      }
      #endregion

      #region Constructor, Dispose
      public IconExListBox() : base()
      {
         this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
      }
      #endregion
   }
}