C# - Színválasztó ListBox kontrol

forráskód letöltése
Amennyiben a felhasználónak színeket kell beállítania az alkalmazásban, ezt több módon teheti meg, hogy kényelmes és látványos is legyen. Cikkünkben elkészítünk egy kontrolt, mely egy listában tartalmazza a színeket megjelenítő kis téglalapokat, valamint a színek nevét, hogy ez is segítsen a döntésben. A kontrol esetében megoldottuk, hogy a kijelölést színnel is jelezzük, valamint hogy a kijelölés eseményéhez kezelőt tudjunk megadni a hívó alkalmazásban.
A kontrol legfontosabb jellemzője, hogy egy property-ben megadható, hogy a Color vagy a SystemColors struktúra elemei jelenjenek meg színek és feliratok formájában a kontrolban , amely a ListBox osztályból származik.
Amennyiben a választás megtörtént, a DrawItem eseménykezelő felülírásával oldhatjuk meg, hogy az egyes elemek helyén egy kis téglalap és a szín neve jelenjen meg. A property neve ColorType, elemei SYSTEM és GENERAL.
A FillArrays metódusban a két struktúra tagjait (színnevek) egy-egy tömbben helyezzük el. A FillControl metódusban pedig az aktuális tömb elemeit helyezzük el a kontrolban. Ezeket a függvényeket a kontrol konstruktorában hívjuk meg.
Annak érdekében, hogy a kontrol elemei egyedileg rajzolhatók legyenek, DrawMode property értéke a következő:
DrawMode = DrawMode.OwnerDrawFixed;
A kontrol még egy property-vel rendelkezik, melynek segítségével lekérdezhetjük az egérrel kiválasztott színt. A property neve SelectedColor.
A Drawitem kezelőfüggvény felülírt változatában nem teszünk mást, mint egy kis 25x12-es téglalapot rajzolunk az adott elem felületére, majd azt kitöltjük a megfelelő színnel.
e.Graphics.DrawRectangle(new Pen(Color.Black),r);
e.Graphics.FillRectangle(new SolidBrush(Color.FromName(item)),r);
e.Graphics.DrawString(item,Font,new SolidBrush(SystemColors.WindowText),e.Bounds.X+35,e.Bounds.Y+1);
Végül a szín nevét is kiírjuk a téglalap után. Az egeret a lista egy eleme fölött felengedve elérhetjük, hogy az adott elem háttérszíne megváltozzon.
e.Graphics.DrawRectangle(new Pen(SystemColors.Highlight),e.Bounds);
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight),e.Bounds);
...
Amikor az egérgombot lenyomjuk, meghatározzuk, hogy mely elemről van szó. Az index meghatározása után már kiválthatjuk a hozzá kapcsolt eseményt. Az esemény kezelője SelectingEventHandler típusú, a deklarációk a következők:
public delegate void SelectingEventHandler(object sender,SelectingEventArgs e);
public event SelectingEventHandler SelectingEvent;
A kezelő második paramétere egy SelectingEventArgs típusú objektum, mely egy saját osztály, három property-vel. A hívó alkalmazásban így lekérdezhetjük a választott színt, annak nevét, valamint az indexet.
Az esemény létrehozása a következőképpen történik a DrawItem metódusban.
OnSelectingEvent(this,new SelectingEventArgs(Color.FromName(syscolors[e.Index]),syscolors[e.Index],e.Index));
A virtuális metódus deklarációja a következő:
protected virtual void OnSelectingEvent(object sender,SelectingEventArgs e) 
{
  if (SelectingEvent != null)
    SelectingEvent(sender,e);
}
A hívó alkalmazásban betöltődéskor meg kell hívnunk a kontrol Execute metódusát, mely gondoskodik arról, hogy a kontrolban minden szín csak egyszer forduljon elő.
clbControl1.Execute();
A fent említett eseményhez egy kezelőre van szükségünk, így deklaráljuk azt.
clbControl1.SelectingEvent += new CLBLibrary.CLBControl.SelectingEventHandler(clbControl1_SelectingEvent);
A metódusban a lekérdezett adatokat felhasználva megjelenítjük a választott szín nevét, majd a TextBox kontrol hátterét be is színezzük az adott színnel.
textBox1.Text = e.ColorName;
if (e.SelectedColor != Color.FromName("Transparent"))
{
  textBox1.BackColor = e.SelectedColor;
}