Witam!
Chcialem w tym temacie zapytac o problem dotyczacy implementacji dzialania drag & drop w kontrolce ListView na przykladzie Menedzera plikow.
Oprocz nawigacji za pomoca zdefiniowanych odpowiednio przyciskow i menu chcialym wykorzystac ten mechanizm drag & drop czyli "przenoszenia myszka", sprawa o tyle moze nie jest trudna jednak w ListView nie moge tego do konca zaimplementowac, teoretycznie powinno dzialac a jednak nie ;/ Aplikacja dziala w ten sposob ze mam 2 okna oparte wlasnie na wspomnianych ListView i chcialbym nawigowac miedzy nim w jedna i w druga strone, chcialbym rownie stworzyc contexmenu aby w wypadku uzycia prawego przycisku myszy uzytkownik mial do wyboru np: 2 opcje - "kopiuj" lub "przenies". Niemniej to to menu juz wiem jak dodac do DragDrop ale sam mechanizm kopiowania i przenoszenia na elementach ListView z jednego do drugiego okna konczy sie niepowodzeniem, moze podam przyklad jak ja to widze:
[Kod C#]private bool mouseWasPressed = false;
private Point mouseLastPos;
private MouseButtons mouseButton;
private DragDropEffects menuEffect;
bool l1_mdown = false;
bool l2_mdown = false;
// ----- naciesniety - sprawdzam wspolrzedne (2 sposoby ;) )
private void listView1_MouseDown(object sender, MouseEventArgs e)
{
l1_mdown = true; // sprawdzam czy nacisnieto przycisk
// mouseWasPressed = true;
* mouseLastPos = new Point(e.X, e.Y); * II wariant - pobieram wspolrzedne myszki, wczesniej sprawdzam czy nacisnieto
// mouseButton = e.Button;
}
private void listView1_MouseUp(object sender, MouseEventArgs e)
{
mouseWasPressed = false;
}
//
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
/*
if ( e.Button == MouseButtons.Right ) return ;
string str = GetItemText(listView1) ;
if ( str == "" ) return ;
listView1.DoDragDrop(str , DragDropEffects.Copy | DragDropEffects.Move );
*/
}
// warunek na to aby nie nastapilo zdarzenie dragdrop w tym samym oknie, aby nie bylo klonowania obiektu
// jezeli nacisnieta sprawdzam czy strzalka ruszyla sie o conajmniej 2 piksele
if ((mouseWasPressed) && (Math.Abs(mouseLastPos.X - e.X) + Math.Abs(mouseLastPos.Y - e.Y) > 2))
{
mouseWasPressed = false;
// Przerwanie operacji w przypadku pustej listy.
if (listView1.Items.Count == 0) return;
// Wyznaczenie indeksu wybranego elementu listy...
ListViewItem srcItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
Point p = this.listView1.PointToClient(new Point(mouseLastPos.X, mouseLastPos.Y));
ListViewItem item = this.listView1.GetItemAt(p.X, p.Y);
int index = this.listView1.Items.IndexOf( item );
// Przerwanie operacji jeśli kursor nie wskazywał żadnego elementu
if (index < 0) return;
// oraz pobranie tekstu spod tego indeksu
string s = listView1.Items[index].ToString();
DragDropEffects ee = DoDragDrop(s, DragDropEffects.Move | DragDropEffects.Copy);
//jeśli operacja zakończyła się efektem DragDropEffects.Move
//(przeniesienie obiektu), należy usuwam obiekt z listy źródłowej
if (ee == DragDropEffects.Move)
listView1.Items.RemoveAt(index);
}
}
// sprawdzam stan przycisku, odpalam efekt kopiowania lub przenoszenia
private void listView1_DragOver(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(ListViewItem)))
{
// Sprawdzamy stan klawisza CTRL (3 bit atrybutu KeyState).
if ((e.KeyState & 8) != 8)
{
// Jeśli nie jest naciśnięty ustawiamy efekt na przenoszenie;
// wyświetlany będzie kursor przenoszenia.
e.Effect = DragDropEffects.Move;
}
else
{
// Jeśli jest naciśnięty ustawiamy efekt na kopiowanie;
// wyświetlany będzie kursor kopiowania.
e.Effect = DragDropEffects.Copy;
}
}
// Jeśli typ przychodzących danych nie jest zgodny z oczekiwaniami,
// ustawiamy efekt na None (kursor zabraniający operacji dragdrop).
else
{
e.Effect = DragDropEffects.None;
}
}
private void listView2_DragDrop(object sender, DragEventArgs e)
{
ListViewItem textBox1 = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
// string textBox1 = e.Data.GetData(DataFormats.Text).ToString();
// string[] items = textBox1.Split(',');
// listView2.Items.Add(new ListViewItem(items, 0));
// lv1_mdown = false;
// lv2_mdown = false;
if (e.Effect != DragDropEffects.None)
{
if (mouseButton == MouseButtons.Right)
{
menuEffect = DragDropEffects.None; // Domyślna wartość menuEffect
// Wyświetlamy menu kontekstowe, pozwalające wybrać żądaną operację.
contextMenu1.Show(listView2, new Point(20, 20));
// Oczekujemy na przetworzenie zdarzenia Click menu kontekstowego.
// Kroku ten ma zapobiec sytuacji, w której wcześniej wykona się
// przypisanie "e.Effect=menuEffect"
Application.DoEvents();
// Ustawiamy zmienną Effect zgodnie z wyborem menu kontekstowego,
// tak aby funkcja DoDragDrop w kontrolce źródłowej zwróciła
// właściwą wartość, umożliwiając ewentualne usunięcie elementu.
e.Effect = menuEffect;
}
// Jeszcze raz sprawdzamy czy dopuszczalne jest "upuszczenie" obiektu,
// ponieważ w przypadku nie wybrania żadnej opcji z menu kontekstowego
// operacja nie powinna być finalizowana.
if (e.Effect != DragDropEffects.None)
{
// Pobieramy "dostarczony" łańcuch znaków...
ListViewItem s = (ListViewItem)e.Data.GetData(typeof( ListViewItem ));
// string s = (string)e.Data.GetData(DataFormats.StringFormat);
// i wstawiamy go do listy.
listView2.Items.Add(s);
}
}
}
private void menuItem1_Click(object sender, EventArgs e)
{
menuEffect = DragDropEffects.Copy;
}
private void menuItem2_Click(object sender, EventArgs e)
{
menuEffect = DragDropEffects.Move;
}
private void listView1_DragDrop(object sender, DragEventArgs e)
{
ListViewItem textBox1 = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
// string[] items = textBox1.Split(',');
listView1.Items.Add(textBox1);
lv1_mdown = false;
lv2_mdown = false;
if (e.Effect != DragDropEffects.None)
{
if (mouseButton == MouseButtons.Right)
{
menuEffect = DragDropEffects.None; // Domyślna wartość menuEffect
contextMenu1.Show(listView1, new Point(20, 20));
Application.DoEvents();
e.Effect = menuEffect;
}
if (e.Effect != DragDropEffects.None)
{
ListViewItem s = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
listView1.Items.Add(s);
}
}
}
private void listView1_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(ListViewItem)))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void listView2_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(ListViewItem)))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void listView2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) return;
string str = GetItemText(listView2);
if (str == "") return;
listView2.DoDragDrop(str, DragDropEffects.Copy | DragDropEffects.Move);
}
a moze jeszcze trzeba zdefiniowac zdarzenie ItemDrag ??
Moze ktos mial podobny problem, prosze o naprowadzenie lub ewentualny fragment kodu odpowiedzialny za dzialanie drag & drop miedzy listview w C#
Z góry dzieki !
pozdrawiam
CaMeL