DDListBoxLibrary kontrol elkészítése
A kontrol projektjét a DDListBoxLibrary alkönyvtár tartalmazza.
Annak érdekében, hogy a kontrol elemeinek vonszolását a kontrol kódjában valósíthassuk meg – vagyis hogy az eseményeket a kontrol kódjában kezelhessük le, és ne a hívó környezetben -, létre kell hoznunk egy saját eseményt a vonszolás eseményének befejezéséhez.
Ez az esemény akkor következik be tehát, amikor az adott elem helye megváltozik. Ezt a pillanatot a példaalkalmazás számára kezelhetővé kell tenni. Az esemény neve ChangeOrder lesz, melyhez egy kezelőt is kell deklarálnunk. Szabályosan ezt úgy tehetjük meg, hogy létrehozunk egy delegáltat:
public delegate void ChangeOrderEventHandler(object sender, ChangeOrderEventArgs e);
Az esemény kezelőmetódusának második paramétere egy saját osztályú objektum lesz, mely az EventArgs osztályból származik.
public class ChangeOrderEventArgs : EventArgs
{
Az eseményparaméter két tagváltozóval rendelkezik, melyek azért szükségesek, hogy a vonszolás végén tartalmazzák az elem régi és új pozícióját.
private int oldorder;
private int neworder;
Az osztály konstruktorában ezeket beállítjuk:
public ChangeOrderEventArgs(int oldord, int neword)
{
oldorder = oldord;
neworder = neword;
}
Természetesen szükség van arra, hogy a változók értékét property-ken keresztül kérdezzük le.
public int OldOrder
{
get
{
return oldorder;
}
}
public int NewOrder
{
get
{
return neworder;
}
}
}
A kontrol osztályában létrehozzuk az eseményt:
public event ChangeOrderEventHandler ChangeOrder;
Valamint egy változót, az adott elem régi pozíciójának tárolására:
A kontrol konstruktorában deklarálunk kezelőket a „Drag and Drop” műveletéhez. Az elem megragadásakor a MouseDown eseményt kell elkapnunk, a vonszoláskor a DragOver, a vonszolás végén pedig a DragDrop eseményt.
public DDListBoxControl()
{
this.MouseDown += new MouseEventHandler(this.control_MouseDown);
this.DragOver += new DragEventHandler(this.control_DragOver);
this.DragDrop += new DragEventHandler(this.control_DragDrop);
this.AllowDrop = true;
}
Az elem megragadásakor eltároljuk az adott egérpozícióban található elem indexét, majd elindítjuk a vonszolást a DoDragDrop függvény meghívásával.
protected void control_MouseDown(object sender, MouseEventArgs e)
{
oldOrder = this.IndexFromPoint(e.X,e.Y); this.DoDragDrop(((ListBox)sender).Items[oldOrder],DragDropEffects.Move);
}
A megragadott elem vonszolásakor lekérdezzük az egérmutató pozícióját, és az adott helyen található elemet jelöljük ki, hogy könnyebben elhelyezhessük a vonszolt elemet. Itt a PointToClient metódussal le kell fordítanunk a fizikai koordinátákat relatív koordinátákká.
protected void control_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
Point screenPoint = new Point(e.X,e.Y);
Point clientPoint = PointToClient(screenPoint);
SelectedIndex = IndexFromPoint(clientPoint.X,clientPoint.Y);
}
A vonszolás befejezésekor, vagyis mikor az elemet elengedjük, elvégezzük a „koordináta-transzformációt”, majd lekérdezzük a cél indexét. Ezt a newOrder változóban tároljuk.
protected void control_DragDrop(object sender, DragEventArgs e)
{
Point screenPoint = new Point(e.X,e.Y);
Point clientPoint = PointToClient(screenPoint);
int newOrder = IndexFromPoint(clientPoint.X,clientPoint.Y);
Majd amennyiben a régi index nem azonos az újjal, és a cél valós, akkor beszúrjuk az elemet az új index által jelölt helyre, majd a régi helyről kitöröljük azt.
if (newOrder != -1 && newOrder != oldOrder)
{
if (oldOrder < newOrder)
{
Items.Insert(newOrder+1,Items[oldOrder]);
Items.RemoveAt(oldOrder);
}
else
{
Items.Insert(newOrder,Items[oldOrder]);
Items.RemoveAt(oldOrder+1);
}
A művelet végén „elsütjük” (event firing) a deklarált eseményt. Az esemény általunk létrehozott paraméterének property-jeit beállítjuk a régi és az új indexekre.
ChangeOrderEventArgs args = new ChangeOrderEventArgs(oldOrder,newOrder);
ChangeOrder(this,args);
}
}
Felhasználása előtt a kontrolt fel kell tenni a ToolBox-ra a szokásos módon: kattintsunk a ToolBox valamely lapján az egér jobb gombjával, majd a megjelenő menüből válasszuk ki a Customize ToolBox pontot, a megjelenő ablakban a .NET Frameworks Components fület. A Browse gombbal keressük elő az imént létrehozott .DLL-t.
Kontrol felhasználása
A Form-ra helyezett label2 címke Text property-jében megjelenítjük a vonszolt elem helyváltoztatására vonatkozó információt. Ennek érdekében deklarálunk egy eseménykezelőt a ChangeOrder eseményre.
this.ddListBoxControl1.ChangeOrder += new DDListBoxLibrary.ChangeOrderEventHandler(this.ddListBoxControl1_ChangeOrder);
Majd a kezelőmetódusban kiolvasva a régi és az új indexeket, megjelenítjük a szöveget:
protected void ddListBoxControl1_ChangeOrder(object sender, DDListBoxLibrary.ChangeOrderEventArgs e)
{
label2.Text = "A(z) " + e.OldOrder.ToString() + ". elem a(z) " + e.NewOrder.ToString() + ". helyre került.";
}