C# - Bélyeg kontrol készítése

forráskód letöltése
Készítsünk egy olyan grafikai kontrolt, melyen megjeleníthető egy tetszőleges kép és a kontrol széle épp úgy szaggatott, mintha csak egy bélyeg lenne. A kontrol készítéséhez ismernünk kell a GDI+ által nyújtott régiói kezelési technikát, melyre cikkünkben is kitérünk.
A megvalósításhoz készítünk tehát egy új kontrolt a Control osztályból származtatva. E kontrol három új property-t tartalmaz.
  • Hole: itt határozhatjuk meg, hogy a „bélyeg” szélén mekkorák legyenek a lyukak
  • Margin: a kontrol széle és a kép közötti margó méretét adja meg
  • Bitmap: itt adhatjuk meg a megjelenítendő képet
Felülírva a kontrol OnPaint függvényét elvégezhetjük a kirajzolást, mely igen egyszerű: ha lett betöltve kép a Bitmap property-be, akkor a Graphics osztály DrawImage függvényével kirajzoljuk, figyelembe véve a kontrol méretét és a megadott margót.
    protected override void OnPaint(PaintEventArgs e)
    {
      if (bitmap!=null)
      {
        e.Graphics.DrawImage(bitmap, Rectangle.Inflate(ClientRectangle, -margin, -margin));
      }
    }
Kissé bonyolultabb feladat a „bélyeg” szélének elkészítése. Ahhoz, hogy a kontrol széle „lyukas” legyen egy olyan régiót kell készítenünk, mely pontosan megfelel a bélyeg kinézetének.
    private void UpdateRegion()
    {
      int i;
      int s2 = hole/2;
      int inc = hole+hole/3;
Ezt a kinézetet egy GraphicsPath osztállyal írjuk le.
      GraphicsPath gp = new GraphicsPath();
Szükségünk lesz két ciklusra, mely végigmegy a kontrol vízszintes és függőleges élein. Mindkét ciklusban két-két AddEllipse függvény hívást végzünk, mely a GrahphicsPath-hoz köröket ad hozzá. Ezek a körök lesznek a kontrol szélein látható lyukak. Ha ügyesen pozícionáljuk ezeket a köröket, akkor a kontrol szélén mindig csak a körök fele fog megjelenni és így egy igazi bélyeg kinézetét adják majd.
      for (i=0; i<Width; i+=inc)
      {
        gp.AddEllipse(i, -s2, hole, hole);
        gp.AddEllipse(i, Height-s2, hole, hole);
      }
      for (i=0; i<Height; i+=inc)
      {
        gp.AddEllipse(-s2, i, hole, hole);
        gp.AddEllipse(Width-s2, i, hole, hole);
      }
Adott tehát egy GraphicsPath, melyben egy téglalap élein elhelyezett körök vannak. Létrehozunk most egy régiót, mely teljesen lefedi a kontrol kliens területét. Ezt követően a Region osztály Exclude függvényét meghívva kizárjuk e régióból azt a területet, melyet a GraphicsPath osztályunk példánya ír le, vagyis a kontrol szélén lévő körök kiesnek a régióból.
      Region r = new Region(this.ClientRectangle);
      r.Exclude(gp);
Most már a régió megfelelő alakú egy bélyeghez képest, így nincs más teendőnk, mint ezt a régiót beállítani a kontrol régiójának.
      this.Region = r;
    }