Sto tentando di eseguire una panoramica del contenuto di un ScrollViewer nello stesso modo in cui si effettua una panoramica in un documento PDF (scorrere per ingrandire/ridurre, fare clic + trascinare per scorrere) ScrollViewer ha questa funzionalità integrata per gli eventi Touch (PanningMode), tuttavia ciò non sembra tradursi in eventi Click + Drag. C'è un modo per dirlo/emulare questa funzionalità?Gain PanningMode del comportamento di ScrollViewer con gli eventi del mouse
risposta
di panning è abilitato internamente da quattro metodi virtuali implementate da ScrollViewer:
OnManipulationCompleted OnManipulationDelta OnManipulationInertiaStarting e OnManipulationStarting
Così dove sono questi metodi virtuali definiti. Andiamo su per la gerarchia. Vediamo che è chiamato su UIElement all'interno di OnManipulationCompletedThunk (sono sicuro che ci sono anche metodi concomitanti per il resto).
A questo punto tutto è ancora privato, vogliamo qualcosa da sfruttare. Sfortunatamente questo è il punto in cui sia Reflector che ILSpy mi hanno fallito (beh, in realtà non è così, il sito di chiamata è in una dll diversa (PresentationCore) che non ho caricato brb). Ok indietro Una volta che guardiamo in PresentationCore, abbiamo una vaga idea che le proprietà di dipendenza siano registrate staticamente, quindi troviamo .cctor. Ci sono un paio di linee di interesse qui.
ManipulationCompletedEvent = Manipulation.ManipulationCompletedEvent.AddOwner (typeof (UIElement));
e
EventManager.RegisterClassHandler (typeof (UIElement), ManipulationCompletedEvent, nuova EventHandler (UIElement.OnManipulationCompletedThunk));
Vediamo che OnManipulationCompletedThunk è il callback registrato per questo gestore di classe che ascolta ManipulationCompletedEvent. Inoltre, ManipulationCompletedEvent non è originariamente definito su UIElement, ma è preso in prestito dalla classe statica Manipulation tramite AddOwner.
Facendo una ricerca per la classe Manipulation, vedo che si trova nello spazio dei nomi System.Windows.Input all'interno dello stesso assembly. È pubblico, sì. Freddo! quindi a questo punto so che se licenzio ManipulationCompletedEvent o qualcuno dei suoi amici, alla fine chiamerà in ScrollViewer. http://msdn.microsoft.com/en-us/library/system.windows.input.manipulation.aspx
Nella documentazione per questa classe statica pubblica, vedo che ci sono un sacco di metodi interessanti e possibilmente utili. L'unico che non è immediatamente ovvio è AddManipulator. Cosa fa questa cosa? Clic .. legge .. oh, "Ogni punto di tocco è un oggetto IManipulator.Ad esempio, se si utilizzano due dita per ridimensionare un oggetto, viene creato un TouchDevice, che implementa IManipulator, per ogni dito." Quindi TouchDevice è un IManipulator. Forse questo mi darà un'idea di come creare il mio manipolatore.
Le proprietà su TouchDevice danno qualche indizio sulle funzionalità supportate. È un po 'come un MouseDevice (ha il concetto di acquisizione, DirectlyOver ecc.), Ma non supporta la manipolazione nello stesso modo. Piuttosto, vogliamo eseguire la manipolazione in risposta agli eventi del mouse. Diamo un'occhiata più difficile a TouchDevice per vedere come implementa realmente alcune di queste funzionalità.
La metodi TouchDevice sta attuando sono getPosition e ManipultionEnded
getPosition restituisce this.GetTouchPoint (relativeTo).Posizione; relativoPer un parametro
ManipulationEnded chiama OnManipulationEnded che inoltra un parametro bool denominato cancel. Non sono sicuro di cosa sia l'annullamento. oh, risulta che non è usato, strano ma ok. In pratica imposta l'acquisizione su null. Kindof alla fine della tana del coniglio qui, quindi dovremo fare un backup e rivalutare.
Tutto quello che voglio veramente fare è aumentare manualmente gli eventi su UIElement e vedere se funziona. Il metodo RaiseEvent su UIElement dovrebbe funzionare per questo. andando a provare brb. Non aspettare, mi sono perso qualcosa, tutti gli eventi definiti nella classe Manipolazione sono contrassegnati come interni.
Chiaramente questi eventi sono pensati solo per il consumo interno e, a meno di fare riflessioni, non abbiamo una strada lì.
Penso che forse usare la funzione Manipolazione sia eccessivo per ciò che si sta tentando di fare. C'è probabilmente un modo per implementarlo con solo un evento di trascinamento e una tela.
Inoltre, trovato questo mentre su Google e pensato che potrebbe essere di una certa rilevanza http://multitouchvista.codeplex.com/