2017-06-04 4 views
1

J'essaie de faire glisser une forme dans un visualiseur de défilement. Ma solution consistait à désactiver temporairement la visionneuse de défilement lorsque je la touchais, puis à la réactiver lorsque je la relâchais. Se sent un peu hacky, mais n'a pas pu trouver une meilleure solution. Quelqu'un at-il une meilleure recommandation?Faites glisser la forme avec le toucher à l'intérieur d'un ScrollViewer UWP

Le code XAML ci-dessous.

<Page 
x:Class="testdragshape.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:testdragshape" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" Height="390.667"> 

<Grid> 
    <ScrollViewer Name="scrollViewer" > 
     <Grid Name="pageGrid"> 
      <TextBlock Name="log" Text="Position:"/> 
      <Canvas Name="myCanvas" Width="500" Height="500"> 
       <Rectangle Name="myTarget" Width="272" Height="272" Fill="Red" Canvas.Left="41" Canvas.Top="53" /> 
      </Canvas> 
     </Grid>    
    </ScrollViewer> 

</Grid> 

Le C# code UWP ci-dessous

using Windows.Foundation; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Input; 
using Windows.UI.Xaml.Media; 

namespace testdragshape 
{ 
    public sealed partial class MainPage : Page 
    { 
     public MainPage() 
     { 
      this.InitializeComponent(); 
      myCanvas.RenderTransform = new TranslateTransform(); 
      myTarget.PointerPressed += Target_PointerPressed; 
      myTarget.PointerMoved += Target_PointerMoved; 
      myTarget.PointerReleased += MyTarget_PointerReleased; 
     } 

     Point _drag0; 
     private void Target_PointerPressed(object sender, PointerRoutedEventArgs e) 
     { 
      // disable the scroll mode 
      scrollViewer.HorizontalScrollMode = ScrollMode.Disabled; 
      scrollViewer.VerticalScrollMode = ScrollMode.Disabled; 

      _drag0 = e.GetCurrentPoint(myCanvas).Position; 
      log.Text = "Position - X: " + _drag0.X + " Y: " + _drag0.Y; 
     } 

     private void Target_PointerMoved(object sender, PointerRoutedEventArgs e) 
     { 
      if (!e.Pointer.IsInContact) return; 

      var point = e.GetCurrentPoint(myCanvas).Position; 
      var t = new Point(point.X - _drag0.X, point.Y - _drag0.Y); 
      TranslateTransform previous = (TranslateTransform)myCanvas.RenderTransform; 
      myCanvas.RenderTransform = new TranslateTransform() 
      { 
       X = previous.X + t.X, 
       Y = previous.Y + t.Y 
      }; 

      log.Text = "Position - X: " + point.X + " Y: " + point.Y; 
     } 

     private void MyTarget_PointerReleased(object sender, PointerRoutedEventArgs e) 
     { 
      // re-enable scroll mode 
      scrollViewer.HorizontalScrollMode = ScrollMode.Auto; 
      scrollViewer.VerticalScrollMode = ScrollMode.Auto; 
     } 
    } 
} 

Répondre

1

Vous y êtes presque, sauf que vous devez désactiver la manipulation directe de ScrollViewer au lieu de désactiver le défilement et le réactiver une fois que vous êtes terminé.

private void OnPointerPressed(object sender, PointerRoutedEventArgs e) 
{ 
    scrollViewer.CancelDirectManipulations(); 
} 

private void OnPointerReleased(object sender, PointerRoutedEventArgs e) 
{ 
    TryStartDirectManipulation(e.Pointer); 
} 
+0

Merci pour la suggestion. Cela fonctionne pour le toucher, mais si vous essayez d'utiliser la souris, alors TryStartDirectManipulation (e.Pointer) donne une erreur System.ArgumentException: 'La valeur ne se situe pas dans la plage attendue.' – ClaudiaWey

+0

C'est vrai parce que les manipulations directes sont conçues pour des gestes tactiles doux. Avec la souris ce que vous faites devrait être bien. –

+1

@MartinZikmund, votre édition est erronée. 'TryStartDirectManipulation' est une méthode * statique *. –