C# - Képeket tartalmazó menü létrehozása

forráskód letöltése
A Visual Studio.NET keretrendszer nemcsak a fejlesztést teszi minden eddiginél könnyebbé és élvezetesebbé funkcionalitásának köszönhetően, de a felhasználói felülete is megújult, tetszetőssé vált. Az egyes menüket legördítve és a menüpontok fölé görgetve az egeret látható, hogy a menüpontok színes keretbe foglalva jelennek meg. Cikkünkben elkészítünk egy menüt, melynek elemei szintén képeket jelenítenek meg a szöveg mellett, és kék keretbe foglalódnak abban az esetben, ha a kurzort föléjük mozgatjuk.
MenuItem leszármazott készítése
A projekt ImageMenuItem.cs állományában találjuk az ImageMenuItem osztály kódját, mely az alkalmazásban létrehozott menü elemeinek osztálya lesz. Lássuk a kódot részletesen.
Annak érdekében, hogy a menüpontban kép jelenhessen meg, létre kell hoznunk egy property-t, mely egy lokális változót állít be. A változó deklarációja a következő:
private Image image;
A változó típusa Image. A property deklarációja pedig:
public Image Image
{
  get
  {
    return image;
  }
  set
  {
    image = value;
  }
}
Az osztály konstruktorában megadjuk, hogy a menüpont rajzolása saját metódusokkal történjen. Ekkor az OwnerDraw property értéke TRUE.
this.OwnerDraw = true;
Illetve deklaráljuk azokat az eseménykezelőket, melyekben a rajzolás megtörténik.
this.MeasureItem += new MeasureItemEventHandler(this_MeasureItem);
this.DrawItem += new DrawItemEventHandler(this_DrawItem);
A menü létrehozásakor, méreteinek beállításakor első lépésként kiszámítjuk, hogy az egyes elemek szövege milyen méretű. Ebből majd kalkuláljuk az adott elem befoglaló méreteit.
Font f = SystemInformation.MenuFont;
SizeF s = e.Graphics.MeasureString(this.Text,f,1000,sf);
Majd amennyiben az image változó értéke nem NULL, akkor lekérdezzük a megadott kép méreteit.
if (image != null)
{
  Bitmap bmp = new Bitmap(image);
  bmpw = bmp.Width;
  bmph = bmp.Height;
}
Végül megadjuk a méreteket, figyelembe véve a fenti számokat.
e.ItemWidth =  (int)Math.Ceiling(s.Width) + bmpw + 15;
e.ItemHeight = (int)Math.Ceiling(s.Height) + 6;
A menüpontok rajzolásakor – attól függően, hogy a menüpont engedélyezett-e vagy sem, illetve hogy a kurzor fölötte van-e, vagy sem – variáljuk a rajzoló- és háttérszíneket. Amennyiben a menüpont engedélyezett és a kurzor fölötte van, akkor kitöltjük a hátterét, és egy keretet is kap.
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.DarkBlue)),e.Bounds.X,e.Bounds.Y,e.Bounds.Width-1,e.Bounds.Height);
e.Graphics.FillRectangle(new SolidBrush(Color.CornflowerBlue),e.Bounds.X+1,e.Bounds.Y+1,e.Bounds.Width-2,e.Bounds.Height-1);
A szöveget is kétféleképpen rajzoljuk ki, igazodva a menüpont aktuális állapotához.
e.Graphics.DrawString(this.Text,f,new SolidBrush(SystemColors.MenuText),(e.Bounds.Left + bmp.Width + 5),(e.Bounds.Top + ((e.Bounds.Height - f.Height) / 2) + 5),sf);
...
ControlPaint.DrawStringDisabled(e.Graphics,this.Text,f,SystemColors.Menu,r,sf);