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();
}