C# - ControlBar kontrol készítése

forráskód letöltése
Cikkünkben elkészítünk egy kontrolt, melyre tetszőleges számú gyermekkontrol rádobható, és képesek vagyunk futási időben fel- illetve legördíteni, eltüntetve vagy megjelenítve a rádobott kontrolokat. A kontrol kapcsán megismerhetjük, hogyan érhetjük el azt, hogy a gyermekek valóban a kontrol részeivé váljanak. A kontrol nyitásának és zárásnak pillanatához külön eseményeket deklaráltunk.
A kontrol a UserControl osztályból származik, és jellegzetessége, hogy egy fejléccel rendelkező panelt ábrázol, melyre szerkesztési időben kontrolok dobhatók. A kontrolok futási időben – a kontrol AddControls metódusának meghívása után – a kontrol gyermekkontroljaivá válnak, koordinátáik a kontrol koordinátáihoz igazodnak.
A kontrol assembly-je két osztályt tartalmaz. A MyButton osztály reprezentálja a kontrol fejlécén megtalálható gombot, melyre kattintva bezárható vagy kinyitható a kontrol.
A gomb osztályának OnPaint metódusában – attól függően, hogy az Opened property értéke TRUE, vagy FALSE – rajzoljuk ki a nyomógomb felületén megtalálható nyilat.
A kontrol osztályában deklaráltunk egy delegáltat a nyitás és a zárás eseményének kezelésére.
public delegate void BarEventHandler(object sender);
A delegált típusával mindjárt létrehoztunk két eseményobjektumot is.
public event BarEventHandler Opening;
public event BarEventHandler Closing;
Mivel a kontrolban két állapotot különítünk el, a rajzoló metódusokban is meg kell vizsgálnunk, hogy éppen melyik állapotban van a kontrol, és ez alapján kell elhelyezni a kirajzoláshoz szükséges pontokat a GraphicsPath objektumban, melyet az osztályban deklaráltunk.
A kontrol OnPaint metódusában rajzoljuk ki a kontrol felületét az Opened property értékétől függően. A metódusban a DrawBar függvénnyel rajzoljuk meg a fejléc területét, rajta a gombbal.
A DrawBorder metódussal rajzoljuk meg a kontrolt szegélyező kék egyeneseket. A kontrol bezárása és kinyitása úgy történik, hogy a magasságot bezáráskor a fejléc magasságának értékére állítjuk, nyitáskor pedig vissza az eredeti értékre.
A kontrol OnMouseDown, OnMouseMove és OnMouseUp metódusainak együttese segítségével megoldottuk, hogy a kontrol futási időben vonszolható legyen az egérmutatóval. Ekkor a területén található kontrolok is vele mozognak.
A kontrol AddControls metódusát a hívó alkalmazás betöltődésekor meg kell hívnunk. Ennek eredményeképpen a területe fölött található kontrolok bekerülnek a kontrol Controls kollekciójába.
A paraméterként kapott Form objektum lesz a kontrol szülőobjektuma, így ennek elemein megyünk végig egy ciklussal.
this.Parent = f;
for(int i=0;i<f.Controls.Count;i++)
{
A kontrolok közül azok kerülnek a kollekcióba, melyek koordinátáik alapján a területe fölött találhatók, és nem önmagával azonos.
  if (f.Controls[i].Left >= Left && f.Controls[i].Left <= Left+Width && f.Controls[i].Top >= Top && f.Controls[i].Top <= Top+Height && !f.Controls[i].Equals(this))
  {
Ekkor a kollekció részévé tesszük, és az adott kontrol Parent property-jének a kontrol objektumát adjuk értékül.
    Controls.Add(f.Controls[i]);
    f.Controls[i].Parent = this;
  }
}
A kontrol kollekcióján ezt követően végigmegyünk, és a nyitó-záró nyomógomb kivételével valamennyi kontrol koordinátáit igazítjuk.
for(int j=0;j<this.Controls.Count;j++)
{
  if (!Controls[j].Equals(hand))
  {
     Controls[j].Left -= Left;
     Controls[j].Top -= Top;
  }
}
A kontrolt a hívó alkalmazásban – miután a ToolBox-on regisztráltuk – csak feldobjuk a Form felületére, és a szükséges kontrolokat elhelyezzük a felületén.
Az Opening és a Closing eseményekhez egy-egy kezelőt írunk, melyben a nyitás és a zárás tényét egy szöveggel konstatáljuk, és megjelenítjük azt az egyik TextBox kontrolban.