Jak widać na screenie, na formatce położyłem dwa labele oraz dwie kontrolki ListBox (listBox1 i listBox2). ListBox1 zawiera elementy które będziemy chcieli umieścić w drugim ListBoxie. Tak więc możemy się umówić że na listBox1 będziemy mówili źródłowy, a listBox2 docelowy.
Zacznijmy od kontrolki źródłowej. Drag & Drop rozpoczyna się przeważnie od „chwycenia myszką” zawartości kontrolki. Jak więc nie trudno się domyślić będziemy musieli obsłużyć zdarzenie MouseDown. W tym momencie kontrolka źródłowa powinna zainicjować operację przenoszenia elementu. Do wykonania tej części będzie konieczne wywołanie metody DoDragDrop. Metoda ta posiada dwa parametry: data typu object (czyli dane które chcemy przenieść) oraz typ wyliczeniowy DragDropEffects. W typie wyliczeniowym możemy znaleźć takie opcje jak:
None – kontrolka docelowa nie pozwala na kopiowanie
Copy – powoduje skopiowanie danych z kontrolki źródłowej do docelowej
Move – przenosi dane z kontrolki źródłowej do docelowej
Link – zostaje utworzone połączenie (logiczne) z elementem docelowym
Scroll – pozwala na przewijanie kontrolki docelowej podczas przenoszenia
All – połączenie efektów Copy, Move i Scroll
Jak więc widać mamy do dyspozycji wiele ciekawych efektów.
To wszystko jeśli chodzi o odpowiedzialność kontrolki źródłowej. Przejdźmy do kontrolki docelowej. Aby możliwe było upuszczenie na docelową kontrolkę jakiegoś elementu, kontrolka musi obsłużyć dwa zdarzenia: DragEnter oraz DragDrop. Zdarzenia te otrzymują parametr DragEventArgs, który zawiera informacje wymagane do wykonania procedury przenoszenia.
Spójrzmy na elementy składające się na DragEventArgs:
AllowedEffect – efekt który jest wspierany przez kontrolkę źródłową
Data – zwraca obiekt typu IDataObject w którym przechowywane są dane z kontrolki źródłowej
Effect – ustala efekt dla kontrolki docelowej
X,Y – współrzędne myszy
KeyState – zwraca stan klawiszy i myszy jako integer:
1 – wciśnięty lewy przycisk myszy
2 – wciśnięty prawy przycisk myszy
5 – wciśnięty klawisz Shift
9 – wciśnięty klawisz Ctrl
16 –wciśnięty środkowy przycisk myszy
32 – wciśnięty przycisk Alt
A więc zbierając wszystkie informacje:
W zdarzeniu DragEnter:
- Za pomocą metody Data.GetDataPresent sprawdzamy czy przekazujemy poprawny typ danych do kontrolki docelowej (np. łańcuch znakowy)
- właściwości Effect używamy aby powiadomić kontrolkę źródłową w jaki sposób kontrolka docelowa odbierze dane
W zdarzeniu DragDrop:
- za pomocą Data.DetData dostajemy się do danych które biorą udział w całym procesie
Przejdźmy teraz może do przykładu. W przykładzie tym spowodujemy, że przy przenoszeniu normalnym dane będą przenoszone, a przy wciśniętym dodatkowo klawiszu Shift kopiowane:
1 /// <summary>
2 /// Obsługa zdarzenia MoudeDown dla kontrolki źródłowej
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void listBox1_MouseDown(object sender, MouseEventArgs e)
7 {
8 //sprawdzamy czy przeciągamy element zawierający jakąkolwiek treść
9 if (listBox1.SelectedIndex >= 0 && listBox1.SelectedItem.ToString() != "")
10 {
11 //zapamiętujemy index
12 int index = listBox1.SelectedIndex;
13 DragDropEffects effect;
14 effect = DoDragDrop(listBox1.Items[index].ToString(), DragDropEffects.Move | DragDropEffects.Copy);
15 //w przypadku przenoszenia kasujemy obiekt z listy
16 //w przypadku kopiowania obiekt pozostanie na liście
17 if (effect == DragDropEffects.Move)
18 {
19 listBox1.Items.RemoveAt(index);
20 }
21 }
22
23 }
24
25 /// <summary>
26 /// Obsługa zdarzenia DragEnter kontrolki docelowej
27 /// </summary>
28 /// <param name="sender"></param>
29 /// <param name="e"></param>
30 private void listBox2_DragEnter(object sender, DragEventArgs e)
31 {
32 //sprawdzamy czy typy się zgadzają, jeśli nie zabraniamy przenoszenia
33 if (e.Data.GetDataPresent(typeof(string)))
34 {
35 if ((e.KeyState & 4) == 4)
36 {
37 e.Effect = DragDropEffects.Copy;
38 }
39 else
40 {
41 e.Effect = DragDropEffects.Move;
42 }
43 }
44 else
45 {
46 e.Effect = DragDropEffects.None;
47 }
48 }
49
50 /// <summary>
51 /// Obsługa zdarzenia DragDrop kontrolki docelowej
52 /// </summary>
53 /// <param name="sender"></param>
54 /// <param name="e"></param>
55 private void listBox2_DragDrop(object sender, DragEventArgs e)
56 {
57 //dodajemy nowy element do listy
58 string newItem = e.Data.GetData(typeof(string)).ToString();
59 listBox2.Items.Add(newItem);
60 }
Podsumowując, aby zaimplementować Drag & Drop musieliśmy
przejść następujące etapy:
To na tyle jeśli chodzi o implementację Drag & Drop.
Oczywiście powyższy kod to tylko przykład. Można by jeszcze dodać obsługę
dwustronną przeciągania itp. Oprócz tekstu można przeciągać także inne elementy
jak np. grafikę. Myślę że teraz implementacja Drag & Drop nie sprawi nikomu
trudności. Powodzenia i udanych eksperymentów.
To w c# ?
OdpowiedzUsuń