C# - Windows-os kontrol szerkesztési-idejű megjelenésének meghatározása

forráskód letöltése
Amellett, hogy tetszőleges megjelenést és funkcionalitást adhatunk Windows-os kontroljainknak, van lehetőségünk arra is, hogy a szerkesztési idejű megjelenést szabályozzuk. A .NET Framework egyik osztálya révén megadhatjuk, hogyan viselkedjen a kontrol akkor, ha valamilyen – a kontrolt érintő – felhasználói beavatkozás történik. Cikkünkben bemutatunk egy példát ennek az osztálynak a felhasználására.
Kontrol osztályának létrehozása
A kontrolunk tulajdonképpen egy számot jelenít meg futási időben. A feladat szempontjából nem lényeges a funkcionalitás bonyolultsága, így most csak egy kisebb feladatot bízunk a kontrolra.
Ha futtatjuk a hívó alkalmazást, akkor a kontrol egy, a Value property-jében megadott értéket rajzol ki a Form felületére. A megvalósítást a kontrol OnPaint metódusában végezzük el.
protected override void OnPaint(PaintEventArgs pe)
{
  Graphics g = pe.Graphics;
  Size clientSize = this.ClientRectangle.Size;
  g.SmoothingMode = SmoothingMode.AntiAlias;
  ...
  g.DrawString(Value.ToString(),Font,sb,posX,posY);
  base.OnPaint(pe);
}
CDVDesigner osztály megvalósítása
A bevezetőben említett funkció megvalósítása érdekében létre kell hoznunk egy szerkesztő osztályt a kontrolhoz, ennek neve CDVDesigner. Az osztály őse a ControlDesigner osztály, melynek OnPaintAdornments metódusát kell felülírnunk ahhoz, hogy a kívánt megjelenítést kölcsönözzük a kontrolnak szerkesztési időben.
A művelet eredményeképpen egy piros keret rajzolódik a kontrol köré, valamint egy kép jelenik meg a kontrol belsejében, szerkesztési időben, ha a kontrol fölé mozgatjuk a kurzort. A szín meghatározásához létrehozunk egy property-t, így elérhetjük, hogy ez a szín állítható legyen szerkesztési időben.
public Color LineColor
{
  get
  {
    return lineColor;
  }
  set
  {
    lineColor = value;
  }
}
Az osztály konstruktorában megadjuk, hogy engedélyezve legyen a vonszolás a kontrol fölött.
public CDVDesigner()
{
  this.EnableDragDrop(true);
}
Az egéresemények kezelésére is van két előre definiált metódus, melyeket felülírunk. Ezekben újrarajzoljuk a kontrol felületét.
protected override void OnMouseEnter()
{
  this.mouseover = true;
  this.Control.Refresh();
}    
Ezután pedig:
protected override void OnMouseLeave()
{
  this.mouseover = false;            
  this.Control.Refresh();
}
Az OnPaintAdornments metódusban rajzoljuk újra a kontrolt. Ebben úgy járunk el, mintha csak a futási idejű megjelenítést manipulálnánk. A PaintEventArgs osztály Graphics tagját használjuk fel a rajzoláshoz.
protected override void OnPaintAdornments(PaintEventArgs pe)
{
  if(this.mouseover)
  {
    pe.Graphics.DrawRectangle(new Pen(new SolidBrush(this.lineColor), 6), 0, 0, this.Control.Size.Width, this.Control.Size.Height);
A képet a kontrol erőforrásai között keressük, és onnan töltjük be egy Bitmap objektumba.
    Bitmap bmp = new Bitmap(GetType().Assembly.GetManifestResourceStream(GetType(),"Sample.ico"));
    ...        pe.Graphics.DrawImage(bmp,(this.Control.Size.Width/2-15),(this.Control.Size.Height/2-15),30,30);
  }
}
A PreFilterProperties metódusban adjuk a LineColor property-t a kontrolhoz.
protected override void PreFilterProperties(System.Collections.IDictionary properties)
{
  properties.Add("LineColor", TypeDescriptor.CreateProperty(typeof(CDVDesigner), "LineColor", typeof(System.Drawing.Color), null));
}
A kontrol osztályának fejlécében meg kell adnunk a fent létrehozott osztályt a DesignerAttribute attribútumban, jelezve, hogy hol található a szerkesztő-osztály kódja.
[DesignerAttribute(typeof(CDVDesigner))]
...