C# (bzw. .NET) bietet uns die Möglichkeit eigene Controls zu erstellen, welche im Designer ebenso eingesetzt werden können wie die bestehenden Controls. Als kleines Beispiel wie man eine solches Control erstellt, habe ich eine kleine ColorComboBox entworfen. Dieses Control bietet noch sehr viel Erweiterungspotential und ist deshalb prima geeignet für diejenigen, welche sich noch nie mit dem erstellen von eigenen Controls beschäftigt haben. Es soll lediglich der Demonstratien dienen, wie eigene Controls erstellt werden.
Als Grundlage dient eine normale Combobox (Stichwort: Vererbung). Dieser Combobox werden einige neue Eigenschaften und Methoden hinzugefügt. Das Herzstück des neuen Controls ist jedoch die Methode “OnDrawItem”, welche die ComboBox in ihrer neuen (farbigen) Form erscheinen lässt. Diese Methode wird implizit aufgerufen, sobald das Control sich neu zeichnen muss. In unserer Variante haben wir die Möglichkeit einen Text und daneben eine beliebige Farbe anzeigen zu lassen. Dies sieht dann etwa so aus:

Der unten aufgeführt Code ist lediglich für die ColorComboBox. Das Demoprogramm welches heruntergeladen werden kann, zeigt wie die ColorComboBox gefüllt werden kann und wie im Design-Modus von Visual Studio daherkommt.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
namespace ColorComboBoxDemo
{
public class ColorComboBox : System.Windows.Forms.ComboBox
{
private bool bCustomColor;
private List<ColorItem> arrColorItems = new List<ColorItem>();
private ColorItem currentItem;
private const string strCustom = "Benutzerdefiniert...";
public ColorComboBox ()
{
//Zeichungsmodus wird festgelegt
this.DrawMode = DrawMode.OwnerDrawFixed;
//Eventhandler werden hinzugefügt
this.DrawItem += new DrawItemEventHandler(OnDrawItem);
this.SelectedIndexChanged += new System.EventHandler(OnSelectedIndexChanged);
this.DropDown += new System.EventHandler(OnDropDown);
}
private void OnDrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
//Ränderabstand wird festgelegt
int padXl = 20;
int padXr = 10;
int padY = 2;
if (e.Index < 0)
{
return;
}
//Momenan aktives ColorItem wird ausgelesen
currentItem = arrColorItems[e.Index];
if (currentItem.ShowOnlyColor == true)
{
padXl = 3;
}
//Grafikzeichner wird instanziert
Graphics grfx = e.Graphics;
//Pinsel für Farbige Rechtecke werden definiert
Color brushColor = currentItem.CurrentColor;
SolidBrush brush = new SolidBrush(brushColor);
//Zeichnungsbereiche werden definiert
Rectangle rectFillBackground = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
Rectangle rectFillColor = new Rectangle(e.Bounds.X + padXl, e.Bounds.Y + padY, e.Bounds.Width - (padXl + padXr), e.Bounds.Height - (2 * padY));
Rectangle rectText;
//Hintergrund wird gezeichnet
grfx.FillRectangle(new SolidBrush(Color.White), rectFillBackground);
if (currentItem.ShowOnlyText == false)
{
//Textbereich wird definiert
rectText = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.X + padXl, e.Bounds.Height - (2 * padY));
//Farbiges Rechteck wird gezeichnet
grfx.FillRectangle(brush, rectFillColor);
//LinieOben
grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl, e.Bounds.Y + padY), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + padY));
//LinieRechts
grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + padY), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1));
//LinieUnten
grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl, e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1), new Point(e.Bounds.X + padXl + (e.Bounds.Width - padXl - padXr), e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1));
//LinieLinks
grfx.DrawLine(new Pen(Color.Black, (float)0.1), new Point(e.Bounds.X + padXl, e.Bounds.Y + padY), new Point(e.Bounds.X + padXl, e.Bounds.Y + e.Bounds.Height - (2 * padY) + 1));
}
else
{
//Textbereich wird definiert
rectText = new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Height);
}
//Text wird gezeichnet
grfx.DrawString(currentItem.Text, e.Font, new SolidBrush(Color.Black), rectText);
//Markierung wird gelöscht
this.SelectionStart = 0;
this.SelectionLength = 0;
}
private void OnSelectedIndexChanged(object sender, System.EventArgs e)
{
//Ausgewähltes Element wird ausgelesen
currentItem = arrColorItems[this.SelectedIndex];
//Wenn es das Benutzerdefinierte Item ist, wird der Farben Dialog angezeigt
if (currentItem.ShowOnlyText == true)
{
ColorDialog dlgColor = new ColorDialog();
if (dlgColor.ShowDialog(this) == DialogResult.OK)
{
//Item mit gewählter Farbe wird eingefügt und selektiert
ColorItem col = new ColorItem();
col.ShowOnlyColor = true;
col.CurrentColor = dlgColor.Color;
arrColorItems.Insert(arrColorItems.Count - 1, col);
this.Items.Insert(this.Items.Count - 1, col);
this.SelectedIndex = this.Items.Count - 2;
}
}
}
private void OnDropDown(object sender, System.EventArgs e)
{
//Ausgewähltes Element wird ausgelesen
if (this.SelectedIndex > -1)
{
currentItem = arrColorItems[this.SelectedIndex];
}
}
public void AddColorItem(Color col, string itemText)
{
ColorItem c = new ColorItem();
c.CurrentColor = col;
c.Text = itemText;
if (bCustomColor == true)
{
if (this.Items.Count == 0)
{
arrColorItems.Insert(0, c);
this.Items.Insert(0, c);
}
else
{
arrColorItems.Insert(this.Items.Count - 1, c);
this.Items.Insert(this.Items.Count - 1, c);
}
}
else
{
arrColorItems.Add(c);
this.Items.Add(c);
}
}
public bool EnableCustomColor
{
get
{
return bCustomColor;
}
set
{
if (bCustomColor == false && value == true)
{
bCustomColor = value;
//Benutzerdefiniertes Item wird eingefügt
ColorItem c = new ColorItem();
c.CurrentColor = Color.White;
c.Text = strCustom;
c.ShowOnlyText = true;
arrColorItems.Add(c);
this.Items.Add(c);
}
if (bCustomColor == true && value == false)
{
bCustomColor = value;
//Benutzerdefiniertes Item wird entfernt
for (int i = 0; i <= arrColorItems.Count - 1; i++)
{
ColorItem c = (ColorItem)arrColorItems[i];
if (c.ShowOnlyText == true)
{
arrColorItems.RemoveAt(i);
this.Items.RemoveAt(i);
}
}
}
}
}
[Browsable(false)]
public Color SelectedColor
{
get
{
return currentItem.CurrentColor;
}
set
{
//Item mit gewählter Farbe wird eingefügt und selektiert
ColorItem col = new ColorItem();
col.CurrentColor = value;
col.ShowOnlyColor = true;
arrColorItems.Insert(arrColorItems.Count - 1, col);
this.Items.Insert(this.Items.Count - 1, col);
this.SelectedIndex = this.Items.Count - 2;
}
}
[Browsable(false)]
public new String SelectedText
{
get
{
return currentItem.Text;
}
set
{
//Item mit entsprechendem Text wird gesucht und selektiert
for (int i = 0; i <= arrColorItems.Count - 1; i++)
{
ColorItem col = (ColorItem)arrColorItems[i];
if (col.Text == value)
{
this.SelectedIndex = i;
break;
}
}
}
}
}
//************************************************************************************************
//------------------------------------------------------------------------------------------------
//************************************************************************************************
public class ColorItem
{
private Color m_Color;
private String m_Text = "";
private bool m_bOnlyText;
private bool m_bOnlyColor;
public ColorItem()
{
}
public Color CurrentColor
{
get { return this.m_Color; }
set { this.m_Color = value; }
}
public String Text
{
get { return this.m_Text; }
set { this.m_Text = value; }
}
public bool ShowOnlyText
{
get { return this.m_bOnlyText; }
set { this.m_bOnlyText = value; }
}
public bool ShowOnlyColor
{
get { return this.m_bOnlyColor; }
set { this.m_bOnlyColor = value; }
}
}
//************************************************************************************************
//------------------------------------------------------------------------------------------------
//************************************************************************************************
}