Erhalte das PanningMode-Verhalten von ScrollViewer mit Mausereignissen

8

Ich versuche, den Inhalt eines ScrollViewers auf die gleiche Weise zu verschieben, wie Sie in einem PDF-Dokument schwenken würden (scrollen Sie, um zu vergrößern / verkleinern, klicken Sie + zum Verschieben). ScrollViewer bietet diese Funktionalität für Touch-Ereignisse (PanningMode), jedoch scheint dies nicht auf Click + Drag-Ereignisse zu übertragen. Gibt es eine Möglichkeit, diese Funktion zu emulieren / zu emulieren?

    
Ben K. 27.02.2012, 16:36
quelle

1 Antwort

2

Das Verschieben wird intern durch vier virtuelle Methoden aktiviert, die von ScrollViewer implementiert werden:

OnManipulationCompleted OnManipulationDelta OnManipulationInertiaStarting und OnManipulationStarting

Wo sind diese virtuellen Methoden definiert? Lasst uns die Hierarchie hochgehen. Wir sehen, dass es auf UIElement innerhalb der OnManipulationCompletedThunk aufgerufen wird (ich bin sicher, dass es auch andere Methoden für den Rest gibt).

An diesem Punkt ist alles noch privat, wir wollen etwas, auf das wir zugreifen können. Leider ist dies der Punkt, an dem mir sowohl reflector als auch ILSpy fehlgeschlagen sind (naja eigentlich hat es nicht geklappt, die Aufrufseite befindet sich in einer anderen dll (PresentationCore) die ich nicht geladen habe). OK zurück. Sobald wir in PresentationCore suchen, haben wir eine vage Idee, dass dependencyProperties statisch registriert werden, also finden wir die .cctor. Es gibt ein paar Zeilen von Interesse hier.

ManipulationCompletedEvent = Manipulation.ManipulationCompletedEvent.AddOwner (typeof (UIElement));

und

EventManager.RegisterClassHandler (typeof (UIElement), ManipulationCompletedEvent, neuer EventHandler (UIElement.OnManipulationCompletedThunk));

Wir sehen, dass OnManipulationCompletedThunk der registrierte Callback für diesen Klassenhandler ist, der auf ManipulationCompletedEvent wartet. Außerdem wurde ManipulationCompletedEvent nicht ursprünglich in UIElement definiert, es wurde von der statischen Klasse "Manipulation" über AddOwner ausgeliehen.

Wenn ich nach der Manipulationsklasse suche, sehe ich, dass sie sich im System.Windows.Input-Namespace innerhalb derselben Assembly befindet. Ist es öffentlich, ja? Cool! An dieser Stelle weiß ich, dass wenn ich das ManipulationCompletedEvent oder irgendeinen seiner Freunde fire, wird es schließlich in ScrollViewer aufrufen. Ссылка

In der Dokumentation für diese öffentliche statische Klasse sehe ich eine Reihe interessanter und möglicherweise nützlicher Methoden. Der einzige, der nicht offensichtlich ist, ist AddManipulator. Was macht das Ding? Klicks .. liest .. oh, "Jeder Berührungspunkt ist ein IManipulator Objekt. Wenn Sie zum Beispiel zwei Finger verwenden, um die Größe eines Objekts zu ändern, wird ein TouchDevice, das IManipulator implementiert, für jeden Finger erstellt." TouchDevice ist also ein IManipulator. Vielleicht gibt mir das eine Idee, wie ich meinen eigenen Manipulator erstellen kann.

Die Eigenschaften von TouchDevice geben Hinweise darauf, welche Funktionen unterstützt werden. Es ist ein bisschen wie ein MouseDevice (hat das Konzept von Capture, DirectlyOver etc.), aber es unterstützt keine Manipulation auf die gleiche Weise. Wir wollen vielmehr Manipulationen als Reaktion auf Mausereignisse durchführen. Sehen wir uns das TouchDevice genauer an, um zu sehen, wie es wirklich einige dieser Funktionen implementiert.

Die Methoden, die TouchDevice implementiert, sind GetPosition und ManipultionEnded

GetPosition liefert this.GetTouchPoint (relativeTo) .Position; relativeTo ist ein Parameter

ManipulationEnded-Aufrufe OnManipulationEnded, die einen bool-Parameter namens cancel weiterleiten. Ich bin mir nicht sicher, was der Abbruch noch tun wird. oh, stellt sich heraus, es ist nicht benutzt, komisch aber ok. Dies setzt Capture grundsätzlich auf null. Irgendwie am Ende des Kaninchenlochs, also müssen wir zurückgehen und neu bewerten.

Alles, was ich wirklich tun möchte, ist, Ereignisse manuell auf dem UIElement auszulösen und zu sehen, ob es funktioniert. Die RaiseEvent-Methode für UIElement sollte dafür geeignet sein. werde versuchen, brb. Ich warte, dass ich etwas verpasst habe. Alle in der Manipulationsklasse definierten Ereignisse sind als intern markiert.

Offensichtlich sind diese Ereignisse nur für den internen Konsum gedacht, und wenn wir nicht darüber nachdenken, haben wir dort keine Möglichkeit.

Ich denke, dass die Verwendung der Manipulationsfunktion für das, was Sie zu tun versuchen, übertrieben ist. Es gibt wahrscheinlich eine Möglichkeit, dies mit nur Drag-Ereignis und einem Canvas zu implementieren.

Auch das wurde beim googeln gefunden und dachte, es könnte von einiger Relevanz sein Ссылка

    
user1834059 21.11.2012, 06:23
quelle

Tags und Links