La mia impresa di oggi si potrebbe definire titanica. Devo implementare all' interno di un programma la funzionalità di Drag and Drop tra due ListBox. Nulla di piu' semplice, se non fosse che la ListBox è l' unico controllo NET (di tipo List) a non esporre un evento ItemDrag ...
Cominciamo con il popolare le due ListBox e selezioniamo la proprietà AllowDrop su true. A questo punto dobbiamo lavorare su un paio di eventi.
Il primo sarà l' evento MouseMove. In questo evento dobbiamo intercettare quale item l' utente sta draggando da una ListBox verso l' altra. Quindi:
private void listBox1_MouseMove(object sender, MouseEventArgs e)
{
//Controllo quale item ha selezionato
int indice = listBox1.IndexFromPoint(e.X, e.Y);
if ((indice >= 0) && (indice < listBox1.Items.Count))
{
listBox1.DoDragDrop
(listBox1.Items[indice], DragDropEffects.Copy);
}
}
A questo punto abbiamo messo in memoria l' item selezionato che stiamo draggando. Il metodo DoDragDrop riceve due parametri. Il primo è di tipo object quindi si deduce che qui possiamo copiare quello che piu' ci aggrada. Il secondo è l' operazione che vogliamo effettuare.
Adesso dobbiamo andare nella ListBox di destinazione e avvisarla che potrebbe ricevere degli items via Drag ... Primo evento scatenato: DragEnter
private void listBox2_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.StringFormat)
&& e.AllowedEffect == DragDropEffects.Copy)
{
e.Effect = DragDropEffects.Copy;
}
}
In questo evento ci assicuriamo che quel che stiamo ricevendo sia un dato corretto proveniente da un Copy, e informiamo l' utente modificando il cursore che diventa quello classico del Drag Drop di WIndows.
Ultima fase è quella di inserire questo oggetto nella listbox di destinazione. Appena andiamo a modifiacre il cursore, l' evento DragEnter termina per rilasciare l' evento DragOver della Listbox di destinazione. Ci siamo preoccupati in precedenza di verificare che l' oggetto fosse di tipo String e non una Bitmap o altro ...
private void listBox2_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.StringFormat))
{
listBox2.Items.Insert (0, e.Data.GetData(DataFormats.StringFormat));
}
}