Wykrywanie jednocześnie dotyku i kliknięcia myszą WPF (MouseDown, TouchDown)

By | 8 kwietnia 2015

Dla niektórych tytuł może być nieco enigmatyczny, więc wyjaśnię w czym tkwi problem. Jeżeli używamy eventu „MouseDown”, to możemy również obsługiwać aplikacje za pomocą dotyku, ale niestety tylko jednego palca na raz, a my chcielibyśmy mieć możliwość obsługi za pomocą kilku punktów dotyku.

Więc następną próbą jest zamiana eventu „MouseDown” na „TouchDown”. Okazuje się, że dzięki temu możemy obsługiwać aplikację za pomocą kilku punktów dotyku, ale straciliśmy możliwość sterowania aplikacji myszką. Czyli ten pomysł też jest nie najlepszy.

Kolejna próba zbliżająca do rozwiązania problemu prawdopodobnie będzie polegać na ustawieniu dwóch eventów jednocześnie, czyli MouseDown i TouchDown. Przy korzystaniu z myszki wszystko działa jak należy, ale przy korzystaniu z dotyku okazuje się, że wszystko wykonuje się jakby dwa razy, ponieważ jednocześnie łapie i „MouseDown” i „TouchDown”.

Tak więc trzeba już tylko wymyślić sposób na rozdzielenie tych dwóch eventów. Można to zrobić w ten sposób:

[csharp]
       private void aplikacja1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            MouseOrTouchApplication1Start(e);
        }

        private void aplikacja1_TouchDown(object sender, TouchEventArgs e)
        {
            MouseOrTouchApplication1Start(e);
        }

        void MouseOrTouchApplication1Start(InputEventArgs e)
        {
            if (e is TouchEventArgs)
            {
                Application1Start();
            }
            else if (e is MouseButtonEventArgs)
            {
                Application1Start();
            }
        }
[/csharp]

Jak widać na załączonym przykładzie użyłem tego kodu do uruchamiania innej aplikacji i dzięki temu zabezpieczeniu uruchomi się ona tylko raz podczas użycia dotyku.

2 thoughts on “Wykrywanie jednocześnie dotyku i kliknięcia myszą WPF (MouseDown, TouchDown)

  1. Kilka_uwag

    Hej,
    znalazłem Twoją stronę i – w ramach wolnego czasu – przeglądam elementy, które zamieszczasz. Pozwolę sobie na kilka komentarzy do kilku wpisów – może się Tobie przydadzą, a może Twoim czytelnikom. Nie wiem czy przeglądasz stare komentarze – ale na to już nie mam wpływu.

    —-

    Nie jest to optymalne rozwiązanie . Powiedziałbym więcej – choć działające, jest moim zdaniem jednym z gorszych.
    Przy każdym kliknięciu musisz rzutować typ eventu i porównywać – przez co wprowadzasz zbędne opóźnienie i obciążenie. O ile w przypadku zdarzeń _Down czy _Up może wydawać się to nawet nienajgorszym pomysłem, to problem powinien być dostrzegalny w przypadku zdarzeń _Move – w szczególności, jeśli wyobrazimy sobie kilka palców równocześnie).

    Bardziej eleganckie będzie stworzenie własnego – nowego urządzenia dotykowego, którego interfejs stanowić będzie mysz.

    Wykorzystać do tego należy klasę TouchDevice w obrębie której wystarczy zaszyć obsługę zdarzeń myszy i przesłonić kilka metod klasy charakterystycznych dla dotyku.

    Korzyści?
    1. Rozwiązanie eleganckie, bardziej optymalne (brak konieczności sprawdzania typu eventargs przy każdym zdarzeniu),
    2. Rzeczywista emulacja dotyku (całej fazy dotyku – a nie wyłącznie zakodowanych eventów – po czymś takim otrzymasz informacje o „dotknięciu” ekranu (pełne TouchEventArgs) pochodzące z Twojego (wraz z Twoim TouchEventArgs.Device). Generowane są więc rzeczywiste TouchEventy – dlatego działać będą rzeczy, które przy Twoim rozwiąazaniu nie zadziałają (np. manipulacje WPF).
    3. Wyniesienie logiki związanej z emulacją poza logikę aplikacji, którą wystarczy zakodować dla dotyku.

    Jeśli już ktoś chce zastosować Twoje rozwiązanie, to sugeruje pozbycie się sprawdzania drugiego warunku, które jest nadmiarowe zakładając rozdzielenie tylko dwóch typów eventów. tj:
    if (e is TouchEventArgs)
    Application1Start();
    else
    Application1Start();

    W razie pytań czy wątpliwości służę pomocą 🙂

    Reply
    1. Paweł Trojanowski Post author

      Dzięki za odpowiedź. Bardzo merytoryczna. Generalnie już od ok. roku nie zajmuję się tworzeniem aplikacji WPF (w tej chwili głównie ASP.NET MVC), to też nie pojawiają się wpisy z tego tematu, a również nie poprawiam starych wpisów, bo brakuje mi wiedzy na ten temat. Ale dziennie wchodzi kilkaset osób, z których część na pewno zwróci uwagę na Twój komentarz 🙂 Skontaktuję się mailowo z Tobą, mam pewną propozycję 🙂

      Reply

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *