using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Data;
using System.Windows.Forms;
using System.Diagnostics;
using UtilityLibrary.General;
namespace UtilityLibrary.WinControls
{
/// <summary>
/// Summary description for ImageComboBox.
/// </summary>
[ToolboxItem(true)]
[ToolboxBitmap(typeof(UtilityLibrary.WinControls.ImageComboBox),
"UtilityLibrary.WinControls.ImageComboBox.bmp")]
public class ImageComboBox : ComboBoxBase
{
#region Class Variables
Bitmap[] bitmapsArray;
string[] bitmapsNames;
ImageList imageList;
bool useImageList = false;
private const int PREVIEW_BOX_WIDTH = 20;
#endregion
#region Constructors
public ImageComboBox()
{
InitializeImageComboBox(null, true, null, null);
}
public ImageComboBox(ImageList imageList)
{
InitializeImageComboBox(imageList, true, null, null);
}
// Run time support only
public ImageComboBox(Bitmap[] bitmapsArray, String[] bitmapsNames)
{
InitializeImageComboBox(null, false, bitmapsArray, bitmapsNames);
}
// Run time support only
public ImageComboBox(Bitmap[] bitmapsArray, String[] bitmapsNames, bool toolBarUse): base(toolBarUse)
{
// To be used when using the combobox in as a ToolBarItem in a ToolBarEx control
InitializeImageComboBox(null, false, bitmapsArray, bitmapsNames);
}
void InitializeImageComboBox(ImageList list, bool useImageList, Bitmap[] bitmapsArray, String[] bitmapsNames)
{
DropDownStyle = ComboBoxStyle.DropDownList;
imageList = list;
this.useImageList = useImageList;
if ( bitmapsArray != null && bitmapsNames != null && useImageList == false )
{
this.bitmapsArray = bitmapsArray;
this.bitmapsNames = bitmapsNames;
for ( int i = 0; i < bitmapsArray.Length; i++ )
{
Items.Add(bitmapsNames[i]);
}
}
}
#endregion
#region Overrides
protected override void DrawComboBoxItem(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
{
// Call base class to do the "Flat ComboBox" drawing
// Draw bitmap
base.DrawComboBoxItem(g, bounds, Index, selected, editSel);
if ( Index != -1)
{
Brush brush;
brush = new SolidBrush(SystemColors.MenuText);
if ( useImageList == false )
g.DrawImage(bitmapsArray[Index], bounds.Left+2, bounds.Top+2, PREVIEW_BOX_WIDTH, bounds.Height-4);
else
g.DrawImage(imageList.Images[Index], bounds.Left+2, bounds.Top+2, PREVIEW_BOX_WIDTH, bounds.Height-4);
g.DrawRectangle(Pens.Black, new Rectangle(bounds.Left+1, bounds.Top+1, PREVIEW_BOX_WIDTH+1, bounds.Height-3));
Size textSize = TextUtil.GetTextSize(g, Items[Index].ToString(), Font);
int top = bounds.Top + (bounds.Height - textSize.Height)/2;
g.DrawString(Items[Index].ToString(), Font, brush,
new Point(bounds.Left + 28, top));
brush.Dispose();
}
}
protected override void DrawComboBoxItemEx(Graphics g, Rectangle bounds, int Index, bool selected, bool editSel)
{
// This "hack" is necessary to avoid a clipping bug that comes from the fact that sometimes
// we are drawing using the Graphics object for the edit control in the combobox and sometimes
// we are using the graphics object for the combobox itself. If we use the same function to do our custom
// drawing it is hard to adjust for the clipping because of these limitations
base.DrawComboBoxItemEx(g, bounds, Index, selected, editSel);
if ( Index != -1)
{
SolidBrush brush;
brush = new SolidBrush(SystemColors.MenuText);
Rectangle rc = bounds;
rc.Inflate(-3, -3);
Pen blackPen = Pens.Black;
g.DrawRectangle(blackPen, new Rectangle(rc.Left+1, rc.Top+1, PREVIEW_BOX_WIDTH+1, rc.Height-3));
if ( useImageList == false )
g.DrawImage(bitmapsArray[Index], rc.Left+2, rc.Top+2, PREVIEW_BOX_WIDTH, rc.Height-4);
else
g.DrawImage(imageList.Images[Index], rc.Left+2, rc.Top+2, PREVIEW_BOX_WIDTH, rc.Height-4);
Size textSize = TextUtil.GetTextSize(g, Items[Index].ToString(), Font);
int top = bounds.Top + (bounds.Height - textSize.Height)/2;
// Clipping rectangle
Rectangle clipRect = new Rectangle(bounds.Left + 31, top, bounds.Width - 31 - ARROW_WIDTH - 4, top+textSize.Height);
g.DrawString(Items[Index].ToString(), Font, brush, clipRect);
brush.Dispose();
}
}
protected override void DrawDisableState()
{
// Draw the combobox state disable
base.DrawDisableState();
// Draw the specific disable state to
// this derive class
using ( Graphics g = CreateGraphics() )
{
using ( Brush b = new SolidBrush(SystemColors.ControlDark) )
{
Rectangle rc = ClientRectangle;
Rectangle bounds = new Rectangle(rc.Left, rc.Top, rc.Width, rc.Height);
bounds.Inflate(-3, -3);
g.DrawRectangle(SystemPens.ControlDark, new Rectangle(bounds.Left+2,
bounds.Top+2, PREVIEW_BOX_WIDTH, bounds.Height-4));
int index = SelectedIndex;
Size textSize = TextUtil.GetTextSize(g, Items[index].ToString(), Font);
// Clipping rectangle
int top = rc.Top + (rc.Height - textSize.Height)/2;
Rectangle clipRect = new Rectangle(rc.Left + 31,
top, rc.Width - 31 - ARROW_WIDTH - 4, top+textSize.Height);
g.DrawString(Items[index].ToString(), Font, b, clipRect);
}
}
}
#endregion
#region Properties
public ImageList Images
{
get{ return imageList;}
set{ imageList = value;}
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public new ComboBox.ObjectCollection Items
{
get { return base.Items; }
}
// Only Run time support
[Browsable(false)]
public Bitmap[] Bitmaps
{
set { bitmapsArray = value; }
get { return bitmapsArray; }
}
// Only Run time support
[Browsable(false)]
public string[] BitmapNames
{
set
{
bitmapsNames = value;
if ( bitmapsNames != null )
{
// Add empty element so that we can get call to draw
// the bitmaps items
for ( int i = 0; i < bitmapsNames.Length; i++ )
{
Items.Add(bitmapsNames[i]);
}
}
}
get { return bitmapsNames; }
}
#endregion
#region Methods
// Designer support
public void PassMsg(ref Message m)
{
base.WndProc(ref m);
}
#endregion
}
}