HyperLink
Bejelentkezés
E-mail: 
Jelszó: 





Skip Navigation Links
 

Egérrel mozgatható képkomponens készítése


Példaprogram letöltése

470224 bájt

Ha egy olyan képet akarunk megjeleníteni egy Form-on, amely nagyobb, mint az a terület, ahová azt rajzoljuk, akkor két lehetőségünk van. Az egyik, hogy a képet lekicsinyítjük úgy, hogy elférjen a rajzterületen. A másik megoldás az, hogy lehetővé tesszük a kép valamilyen módon történő görgetését. Ebben a példában egy olyan komponenst készítünk, amely ez utóbbi feladatot oldja meg.

A kontrolt úgy készítettük el, hogy megadhassunk egy képet, melyet megjelenít, valamint megadhassuk a kép relatív X és Y koordinátáját. E három adat megadásához három property-t hoztunk létre, melyek nevei rendre a következők:
  • Picture
  • ImageTop
  • ImageLeft
A kép – ennek hiányában egy szöveg – megjelenítése a kontrol OnPaint metódusában történik. Ha nem adtunk meg képet, akkor a „Nincs kép” feliratot írjuk a keretbe. Ezt a Graphics objektum DrawString metódusával végezzük el.
if (picture == null)
{
  e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Black)),ClientRectangle.X,ClientRectangle.Y,ClientRectangle.Width-1,ClientRectangle.Height-1);
Hogy a szöveg a keret mértani közepére kerüljön, a MeasureString metódussal lekérdezzük a szöveg fizikai méreteit, majd kalkuláljuk a rajzolási pozíciót.
  string str = "Nincs kép";
  SizeF s = e.Graphics.MeasureString(str,Font);
  int x = (ClientRectangle.Width - (int)s.Width)/2;
  int y = (ClientRectangle.Height - (int)s.Height)/2;
  e.Graphics.DrawString(str,Font,new SolidBrush(Color.Black),x,y);
}
Ha van kép, akkor a DrawImage metódussal minden nehézség nélkül kirajzolhatjuk.
else
{
  e.Graphics.DrawImage(picture,imageleft,imagetop,picture.Width,picture.Height);
...
Amennyiben a kép „túllóg” a kereten, vagyis méretei meghaladják annak méreteit, akkor az egérrel vonszolva igazíthatjuk, görgethetjük azt. Ehhez három eseményre kell kezelőmetódust írnunk. Annak érdekében, hogy az egér pozíciójából következtethessünk arra, hogy az adott pozíció a kép területén van-e vagy sem, fel kel használnunk egy API függvényt, nevezetesen a user32.dll-ben deklarált PtInRect metódust.
[DllImport("User32.dll")]
public static extern bool PtInRect(ref Rect r, NewPoint p);
Paraméterekként olyan adatstruktúrákat adunk át, melyeknek menedzselt megfelelőit magunk deklaráltunk. Az egyik egy NewPoint nevű struktúra, melyben a kérdéses pont koordinátáit adjuk meg.
[StructLayout(LayoutKind.Sequential)]
public struct NewPoint 
{
  public int x;
  public int y;
}
A másik adattípus is egy struktúra, melyben a téglalap adatait adhatjuk át, melyre a lekérdezés vonatkozik.
[StructLayout(LayoutKind.Explicit)]
public struct Rect 
{
  [FieldOffset(0)] public int left;
  [FieldOffset(4)] public int top;
  [FieldOffset(8)] public int right;
  [FieldOffset(12)] public int bottom;
}
Az egér gombjának lenyomásakor megvizsgáljuk, hogy a kurzor pontja benne van-e a kép területét lefedő téglalapban. Amennyiben igen, akkor megváltoztatjuk a kurzort, és kiváltjuk a kontrolhoz kapcsolt három esemény egyikét.
...
if (e.Button == MouseButtons.Left && PtInRect(ref rect,pt) && picture != null)
{
  Cursor = Cursors.Hand;
  dragging = true;
  dragpos = new Point(e.X,e.Y);
  OnDragStart(new EventArgs());
}
Az egér mozgatásakor (OnMouseMove metódus) végezzük el a kép görgetését, vagyis az ImageLeft és ImageTop property-k értékét úgy módosítjuk, ahogy éppen az egeret mozgatjuk.
dx = dragpos.X - e.X;
dy = dragpos.Y - e.Y;
if (ValidateLeftPos(imageleft-dx))
{
  imageleft = imageleft - dx;
}
if (ValidateTopPos(imagetop-dy))
{
  imagetop = imagetop - dy;
}
...
Az egér gombjának felengedésekor (OnMouseUp metódus) visszaállítjuk a kurzort.
if (dragging)
{
  dragging = false;
  Cursor = Cursors.Default;
  ...
}
A ValidateLeftPos és a ValidateTopPos metódusok szolgálnak arra, hogy a kép pozíciójának koordinátáit megvizsgáljuk, és eldöntsük, hogy a kép adott pozíciójának számértékének és a kép adott tulajdonságának összege meghaladja-e a befoglaló terület adott tulajdonságának értékét.
Az ImageTop és ImageLeft property-k értékeként csak negatív számok adhatók meg.
Az alkalmazásban a kontrol eseményeit használjuk fel arra, hogy a vonszoláskor megjelenítsük egy ToolTip objektum feliratában a kép aktuális koordinátáit. A DraggingEvent és a DragEndEvent eseményekre írunk kezelőt.
cmiControl1.DraggingEvent += new EventHandler(cmiControl1_DraggingEvent);
cmiControl1.DragEndEvent += new EventHandler(cmiControl1_DragEndEvent);
A vonszoláskor beállítjuk a ToolTip szövegét.
private void cmiControl1_DraggingEvent(object sender, EventArgs e)
{
  toolTip1.SetToolTip(cmiControl1,"X koordináta: " + cmiControl1.ImageLeft.ToString() + " px" + '\u000D' + "Y koordináta: " + cmiControl1.ImageTop.ToString() + " px");      
}
Míg a vonszolás végén töröljük ezt a bejegyzést, hogy a tipp eltűnjön a képernyőről.
private void cmiControl1_DragEndEvent(object sender, EventArgs e)
{
  toolTip1.RemoveAll();
}

Könyv
Ez a cikk megtalálható ebben a könyvben: C# Software Offline 2003 évkönyv 717. oldal

Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!

Copyright © 1999-2012 Animare Software Kft. Minden jog fenntartva!
| Készült: Animare Stúdió | Adatvédelem | Kapcsolat |