2013-03-10 48 views
8

Mam metodę Drag() na zdarzenie form_MouseDown. Mam również zdarzenie kliknięcia w formularzu. Problem polega na tym, że po kliknięciu formularza zdarzenie MouseDown zostanie uruchomione i nigdy nie uzyska szansy na wywołanie zdarzenia kliknięcia.Konflikt MouseDown i Click

Jaki jest najlepszy sposób rozwiązania tego problemu? Zastanawiam się nad liczeniem pikseli, jeśli formularz jest faktycznie przeciągnięty, ale musi być lepszy sposób. Jakieś sugestie?

+0

„liczenie pikseli” jest dość powszechne, ponieważ w większości przypadków rzeczywiście nie chcą ** ** przeciągania odpalać kiedy "odległość ruchu" jest krótsza niż na przykład 7..15 pikseli. Nawet pulpit Windows ma taki próg kilku pikseli. – quetzalcoatl

+2

Nie należy używać opcji 'Kliknąć' i zamiast niej używać' MouseUp'? – Neolisk

+0

Stworzyłem demo i nie dostaję tego zachowania. Po osiągnięciu MouseDown Click. Czy możesz napisać jakiś kod? –

Odpowiedz

2

Zastanawiam się nad liczeniem pikseli, jeśli formularz jest rzeczywiście przeciągnięty, ale musi być lepszy sposób.

Nie, dokładnie tak trzeba to zrobić.

To nie jest tylko ograniczenie oprogramowania; to także bardzo praktyczne. Jeśli podejmiesz problem z perspektywy użytkownika, natychmiast zobaczysz problem, a także rozwiązanie. Zadaj sobie pytanie, jaka jest różnica między kliknięciem a przeciągnięciem?

Obydwa zaczynają się od naciśnięcia przycisku myszy nad obiektem, ale jeden z nich kończy się kliknięciem myszki w górę nad obiektem w tej samej pozycji, a drugi kończy się po kliknięciu myszką w górę. zupełnie inna pozycja.

Od czasu maszyn jeszcze nie zostały udoskonalone, nie masz możliwości, aby wiedzieć z góry.

Tak, musisz utrzymywać pewien próg odległości, a jeśli wskaźnik porusza się poza próg odległości, gdy znajduje się nad obiektem, to uważasz go za opór. W przeciwnym razie uważasz to za kliknięcie.

Ten próg odległości nie powinien wynosić 0. Użytkownik nie powinien być zmuszony do trzymania myszki całkowicie nieruchomej w celu zainicjowania przeciągnięcia. Wielu użytkowników jest podporządkowanych. Jest bardzo prawdopodobne, że będą lekko drgać podczas próby kliknięcia. Jeśli próg jest równy 0, w końcu spróbują kliknąć, co spowoduje nieumyślne przeciągnięcie.

Oczywiście, nie musisz się o nic martwić ani samodzielnie obliczyć wartości progowej.Zamiast tego użyj wartości domyślnych systemu Windows, które można uzyskać, wywołując funkcję GetSystemMetrics i podając SM_CXDRAG lub SM_CYDRAG. (To może być narażona gdzieś ramami WinForms, ale nie sądzę. To tak samo łatwe do P/Invoke je samodzielnie.)

const int SM_CXDRAG = 68; 
const int SM_CYDRAG = 69; 
[DllImport("user32.dll")] 
static extern int GetSystemMetrics(int index); 

Point GetDragThreshold() 
{ 
    return new Point(GetSystemMetrics(SM_CXDRAG), GetSystemMetrics(SM_CYDRAG)); 
} 
+0

Chociaż ogólnie masz tutaj dobre punkty, program powinien być zaprojektowany w taki sposób, aby przeciąganie i upuszczanie czegokolwiek 5px na bok nie powodowało niczego. W przeciwnym razie nigdy się nie dowiesz, być może, że 5px shake nie wystarczy, aby niektórzy ludzie kliknęli i potrzebują 10px. Przy prawidłowej implementacji ruchy myszy są nieistotne. Na przykład, jeśli upinasz i upuszczasz plik w systemie Windows, nic się nie dzieje. – Neolisk

+0

Wyobraź sobie, że tworzysz projektanta WinForm. Nawet jeśli poprawnie zaimplementowane, ruch myszy jest nadal istotny. Jest to zupełnie inny projekt niż Eksplorator Windows, w którym nie ma sensu upuszczać ikony na siebie. Ale możesz oczywiście przeciągnąć kontrolkę o kilka pikseli w dowolnym kierunku. Lub wybór w edytorze zdjęć. Lub dowolną liczbę innych przypadków, w których reguła "właściwej implementacji" nie będzie działać. –

+0

W tych przypadkach należy użyć pozycjonowania klawiatury (klawisze strzałek). Robi to dokładnie - przesuń się w wyznaczonym kierunku o 1 piksel. W przeciwnym razie chciałbyś, na przykład w VS, kontroli trzymać się siatki formularza lub innych formantów. W obu przypadkach VS pomoże Ci w pozycjonowaniu. W programie Photoshop lub Paint można: 1) użyć klawiszy strzałek lub 2) zmniejszyć widok do momentu, w którym poruszanie się o kilka pikseli w dowolnym kierunku staje się nieistotne. – Neolisk

2

Niestety, w momencie, gdy "naciśnięty przycisk" nie wiesz jeszcze, czy pożądana czynność to tylko kliknięcie czy przeciągnięcie. Przekonasz się, że to później.

Dla kliknięcia wyznacznikiem jest "brak ruchu" i "przycisk w górę".

Dla przeciągania wyznacznikiem są "ruch" i "przycisk w górę".

Dlatego, aby ujednoznacznić te interakcje, trzeba śledzić nie tylko przyciski, ale także ruch. Nie musisz śledzić ogólnego ruchu, interesujący jest tylko ruch pomiędzy przyciskami i przyciskami.

zdarzenia te są zatem dobrym miejscem do start/stop mechanizmy Mouse.Capture (dynamicznie obecny drag adorners położenie i spadek wskazówki), lub w postaci prostszy - przechowywanie pochodzenie i celu przemieszczania wektor i sprawdź, czy odległość jest> D (nawet jeśli wystąpił ruch, powinna być pewna bezpieczna minimalna odległość, w której DRAG jest anulowana.Moja mysz jest czasami "szczupła" i ludzie naprawdę nie lubią, gdy twoja aplikacja zaczyna się przeciągać po dwukrotnym kliknięciu na końcu szybkiego ruchu wskaźnika myszy :))

2

znalazłem to rozwiązanie, choć jest o pokojach dwuosobowych kliknij myszką w dół i wydarzenia:

void pictureBox_MouseDown(object sender, MouseEventArgs e) 
{ 
if (e.Button == MouseButtons.Left && e.Clicks ==1) 
{ 
PictureBox pb = (PictureBox)sender; 
DoDragDrop((ImageData)pb.Tag, DragDropEffects.Copy); 
} 
} 

źródło: http://code.rawlinson.us/2007/04/c-dragdrop-and-doubleclick.html

Powiązane problemy