Full code for ComboBox OwnerDraw
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Diagnostics;
namespace WindowsApplication73 {
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form {
private System.Windows.Forms.ComboBox comboBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public Form1() {
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
comboBox1.Items.Add("Apple");
comboBox1.Items.Add(new SeparatorItem("orange"));
comboBox1.Items.Add("Dog");
comboBox1.Items.Add(new SeparatorItem("Cat"));
comboBox1.Items.Add("Boy");
comboBox1.Items.Add("Girl");
}
public class SeparatorItem {
private object data;
public SeparatorItem(object data) {
this.data = data;
}
public override string ToString() {
if (data != null) {
return data.ToString();
}
return base.ToString();
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing) {
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// comboBox1
//
this.comboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
this.comboBox1.Location = new System.Drawing.Point(64, 80);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(121, 21);
this.comboBox1.TabIndex = 0;
this.comboBox1.Text = "comboBox1";
this.comboBox1.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.comboBox1_MeasureItem);
this.comboBox1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.comboBox1_DrawItem);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.comboBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new Form1());
}
private const int separatorHeight = 3, verticalItemPadding = 4;
private void comboBox1_MeasureItem(object sender, System.Windows.Forms.MeasureItemEventArgs e) {
if (e.Index == -1) {
return;
}
else {
object comboBoxItem = comboBox1.Items[e.Index];
// in Whidbey consider using TextRenderer.MeasureText instead
Size textSize = e.Graphics.MeasureString(comboBoxItem.ToString(), comboBox1.Font).ToSize();
e.ItemHeight = textSize.Height + verticalItemPadding;
e.ItemWidth = textSize.Width;
if (comboBoxItem is SeparatorItem) {
// one white line, one dark, one white.
e.ItemHeight += separatorHeight;
}
}
}
private void comboBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) {
if (e.Index == -1) {
return;
}
else {
object comboBoxItem = comboBox1.Items[e.Index];
e.DrawBackground();
e.DrawFocusRectangle();
bool isSeparatorItem = (comboBoxItem is SeparatorItem);
// draw the text
using (Brush textBrush = new SolidBrush(e.ForeColor)) {
Rectangle bounds = e.Bounds;
// adjust the bounds so that the text is centered properly.
// if we're a separator, remove the separator height
if (isSeparatorItem && (e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit) {
bounds.Height -= separatorHeight;
}
// Draw the string vertically centered but on the left
using (StringFormat format = new StringFormat()) {
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Near;
// in Whidbey consider using TextRenderer.DrawText instead
e.Graphics.DrawString(comboBoxItem.ToString(), comboBox1.Font, textBrush, bounds, format);
}
}
// draw the separator line
if (isSeparatorItem && ((e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit)) {
Rectangle separatorRect = new Rectangle(e.Bounds.Left, e.Bounds.Bottom - separatorHeight, e.Bounds.Width, separatorHeight);
// fill the background behind the separator
using (Brush b = new SolidBrush(comboBox1.BackColor)) {
e.Graphics.FillRectangle(b, separatorRect);
}
e.Graphics.DrawLine(SystemPens.ControlText, separatorRect.Left + 2, separatorRect.Top + 1,
separatorRect.Right - 2, separatorRect.Top + 1);
}
}
}
}
}
[EDIT 8/31/2005: support comboBox1.DropDownStyle = ComboBoxStyle.DropDownList: bitwise AND the check for ComboBoxEdit and protect against events with negative index]
Comments
- Anonymous
August 26, 2005
A question came up the other day about how to add a separator to a ComboBox, and unfortunately the answer... - Anonymous
August 26, 2005
A question came up the other day about how to add a separator to a ComboBox, and unfortunately the answer... - Anonymous
August 26, 2005
A question came up the other day about how to add a separator to a ComboBox, and unfortunately the answer...