C# - Egyedi színválasztó kontrol készítése

forráskód letöltése
Fejlesztéskor gyakran van szükség arra, hogy lehetővé tegyük a felhasználó számára a felület egyes részeinek testre szabását színek tekintetében. A színek kiválasztásához alkalmazhatjuk azt a módszert, hogy a Visual Studio.NET beépített ColorDialog kontroljának felületén választhat a felhasználó. Cikkünkben elkészítünk egy Windows-os színválasztó kontrolt, mely alternatívája lehet az említett kontrolnak.
SelectColorLibrary elkészítése
A kontrolunk megjelenésében egy ComboBox kontrolra emlékeztet, ha a kiválasztott színt megmutató panelen egyet kattintunk, akkor „legördül” egy ablak, mely a választható színeket tartalmazza egy kétdimenziós mátrixban. A hatás elérése érdekében a kontrolunk tehát két részből áll: egy Button kontrolból származtatott osztályból, és egy felbukkanó ablakból, mely a Form-osztályból származik. Kezdjük a kontrol első részével, melynek kódja a SelectColorControl.cs állományban található.
A kontrol egy tagváltozót tartalmaz, mely befogadja a gomb hátterének színét:
public class SelectColorControl : System.Windows.Forms.Button
{
  private Color centerColor;
Az ezt állító property:
  public Color CenterColor
  {
    get{ return centerColor; }
    set{ centerColor = value; }
  }
A kontrol konstruktorában a kontrolhoz deklarálunk négy eseménykezelőt, melyek akkor zajlanak le, ha a kontrol fölé ér az egérmutató, elhagyja a kontrol területét, vagy a lenyomott egérgombot felengedjük. A negyedik eseménykezelőt a kontrol Paint eseményéhez kapcsoljuk:
public SelectColorControl()
{
  Paint += new PaintEventHandler(ButtonPaint);
  MouseEnter += new EventHandler(OnMouseEnter);
  MouseLeave += new EventHandler(OnMouseLeave);
  MouseUp += new MouseEventHandler(OnMouseUp);
}
Az egéreseményeket kezelő függvények mindegyikében az Invalidate metódust hívjuk meg, hogy a szín kiválasztása után (ennek folyamatát öleli fel a három egéresemény-kezelő) a felületen megjelenjen a választott szín.
A kontrol Paint eseményéhez rendelt kezelőben gondoskodunk arról, hogy a kontrol megjelenése „ComboBox”-os legyen:
void ButtonPaint(object sender, PaintEventArgs e)
{          
  Graphics g = e.Graphics ;
  ...
}
A metódusban két fő műveletet hajtunk végre. Az első a választott színt megjelenítő téglalap kirajzolása egy Rectangle objektummal, kitöltő színként megadva a centerColor tagváltozó értékét. A második, hogy megrajzoljuk a fekete nyilat, mely tulajdonképpen háromszor két pont összekötése a Graphics osztály DrawLine metódusával megfestve a behatárolt háromszöget. A két objektumot egy kis vonallal választjuk el egymástól.
A kontrol projektjének ColorDlg.cs állományában helyeztük el a felbukkanó dialógusablak kódját, melyben 40 kis Panel objektum jelöli a választható színeket:
Panel[] panel = new Panel[40];
Ehhez létre kell hoznunk egy 40 elemes tömböt a színek számára:
Color[] color = new Color[40]{...};
A Form két tagobjektuma két Button kontrol, melyek egyikét megnyomva további színeket választhatunk egy ColorDialog ablakban. A másik gomb láthatatlan, erre csak azért van szükségünk, hogy egy ESC billentyűre eltűnjön a panel:
Button moreColorsButton = new Button();
Button cancelButton = new Button();
A választott színt egy tagváltozó tárolja:
Color selectedColor;
A property:
public Color Color
{
  get {return selectedColor;}
}
Létrehozunk egy konstruktort a Form osztályhoz az alapértelmezett konstruktoron kívül – két paramétert fogad - annak érdekében, hogy a panel helyét igazíthassuk. A bemenő paraméterek ugyanis a befogadó Windows-os alkalmazás Form-jára feltett gomb koordinátái, melyekből számítjuk ablakunk pozícióját:
public ColorDlg(int x, int y)
{
  ...
}
A konstruktorban beállítjuk a megjelenésre vonatkozó adatokat, és a gombok jellemzőit.
A Form BuildPalette metódusában gondoskodunk az ablak felépítéséről, melynek záróakkordja egy eseménykezelő deklarálása a szín kiválasztásának eseményéhez, mely akkor következik be, amikor az egyik kis színpanel fölött felengedjük az egérgombot. A kis panelekhez rendeltünk még egéresemény-kezelőket, melyekkel kicsit látványossá tehetjük azt a pillanatot, amikor a mutató elér egy panelt.
void BuildPalette()
{
  ...
  panel[i].MouseUp += new MouseEventHandler(OnMouseUpPanel);
  ...
}
A kis Panel objektumokat meghatározott rendben egy mátrixba rendezzük, beállítjuk háttérszínüket. Ehhez elkészítettünk egy DrawPanel metódust, mely megváltoztatja a kis panelek keretének hatásait, így érve el, hogy a Panel „kiemelkedik”, amikor az egérrel fölé érünk.
A Form-on egy kis panelre kattintva a szín megjelenik a választógomb felszínén, miközben az ablak bezáródik:
void OnMouseUpPanel(object sender, MouseEventArgs e)
{      
  Panel panel = (Panel)sender;    
  selectedColor = panel.BackColor;
  DialogResult = DialogResult.OK;
  Close();
}
Felhasználása előtt a kontrolt fel kell tenni a ToolBox-ra a szokásos módon: kattintsunk a ToolBox valamely lapján az egér jobb gombjával, majd a megjelenő menüből válasszuk ki a Customize ToolBox pontot, a megjelenő ablakban a .NET Frameworks Components fület. A Browse gombbal keressük elő az imént létrehozott .DLL-t.
A kontrol felhasználása
Bizonyos pozícionálási okok miatt a megjelenítést a kontrolhoz a befogadó alkalmazásban deklarált kezelőfüggvénnyel oldjuk meg. Megtehettük volna a kontrolban is, de ekkor a választó dialógusablakunk nem a megfelelő helyen bukkanna fel. Az eseménykezelőben egyszerűen kikalkuláljuk a gomb pozíciójából a megjelenő ablak x és y koordinátáját:
Point p = new Point(selectColorControl1.Left, selectColorControl1.Top + selectColorControl1.Height);
p = PointToScreen(p);
Az ablakot példányosítjuk a konstruktorában megadva a két koordinátát és megjelenítjük:
SelectColorLibrary.ColorDlg dlg = new SelectColorLibrary.ColorDlg(p.X, p.Y);
dlg.ShowDialog();  
A visszatérési értéket megadjuk a gomb háttérszíneként:
if(dlg.DialogResult == DialogResult.OK)
  color = dlg.Color;
selectColorControl1.CenterColor = color;
...