2010-12-15 26 views
0

Pour une application à écran tactile compatible, je souhaite modifier les commandes standard ScrollViewer dans mon application WPF 3.5: Au lieu de montrer les barres de défilement, je veux que l'utilisateur de faire défiler en cliquant dans la zone de contrôle et en faisant glisser le contenu (similaire au comportement sur l'iPhone d'Apple). Je voudrais faire cela en appliquant un style au ScrollViewer, car (a) je peux appliquer un style automatiquement à n'importe quel ScrollViewer dans une fenêtre (même ceux contenus dans les contrôles comme ListView) et (b) je peux utiliser le Windows standard Scrollbar-style si l'application est en cours d'exécution sur un bureau normal avec le clavier et la souris.Est-il possible d'implémenter un comportement "slide-to-scroll" pour ScrollViewer?

Ma première idée était d'utiliser un modèle de contrôle personnalisé pour le ScrollViewer. Le modèle de contrôle par défaut est described in the MSDN et utilise un ScrollContentPresenter. Normalement, je dériverais juste une classe de ScrollContentPresenter et j'ajouterais le comportement de slide-to-scroll là, mais pour une raison quelconque, ScrollContentPresenter est scellé - je ne peux pas en dériver. J'ai essayé de placer un ScrollContentPresenter dans un UserControl, et de mettre le contrôle de l'utilisateur dans le modèle de contrôle ScrollViewer, mais cela ne fonctionnait pas non plus.

Yat-il un moyen simple d'obtenir ce comportement, sans réécrire toutes les fonctionnalités ScollViewer/ScrollContentPresenter?

Répondre

1

Mise à jour
a fait les barres de défilement Invisible et ajouté MouseLeave pour libérer le défilement

Glisser ScrollViewer avec un rectangle à l'intérieur

<Grid Width="500" 
     Height="250"> 
    <ScrollViewer Name="slideScrollViewer" 
        Style="{StaticResource slideScrollViewer}" 
        HorizontalScrollBarVisibility="Auto" 
        VerticalScrollBarVisibility="Auto"> 
     <Rectangle Width="1000" 
        Height="500"> 
      <Rectangle.Fill> 
       <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> 
        <GradientStop Offset="0.0" Color="Red"/> 
        <GradientStop Offset="0.33" Color="Green"/> 
        <GradientStop Offset="0.66" Color="Blue"/> 
       </LinearGradientBrush> 
      </Rectangle.Fill> 
     </Rectangle> 
    </ScrollViewer> 
</Grid> 

SlidingScrollViewer.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        x:Class="StyleScrollViewer.SlidingScrollViewer"> 
    <Style x:Key="slideScrollViewer" TargetType="ScrollViewer"> 
     <Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/> 
     <Setter Property="VerticalScrollBarVisibility" Value="Hidden"/> 
     <EventSetter Event="PreviewMouseLeftButtonDown" Handler="slideScrollViewer_PreviewMouseLeftButtonDown"/> 
     <EventSetter Event="PreviewMouseLeftButtonUp" Handler="slideScrollViewer_PreviewMouseLeftButtonUp"/> 
     <EventSetter Event="MouseMove" Handler="slideScrollViewer_MouseMove"/> 
     <EventSetter Event="MouseLeave" Handler="slideScrollViewer_MouseLeave"/> 
    </Style> 
</ResourceDictionary> 

SlidingScrollViewer. xaml.cs

public partial class SlidingScrollViewer 
{ 
    private bool m_isCaptured = false; 
    Point m_lastCoordinate = new Point(-1, -1); 
    private void slideScrollViewer_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     m_isCaptured = true; 
    } 
    private void slideScrollViewer_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     m_isCaptured = false; 
     m_lastCoordinate.X = -1; 
    } 
    private void slideScrollViewer_MouseMove(object sender, MouseEventArgs e) 
    { 
     if (m_isCaptured == true) 
     { 
      ScrollViewer scrollViewer = sender as ScrollViewer; 
      Point coordinate = e.GetPosition(scrollViewer); 
      if (m_lastCoordinate.X >= 0) 
      { 
       scrollViewer.ScrollToHorizontalOffset(scrollViewer.HorizontalOffset + (m_lastCoordinate.X - coordinate.X)); 
       scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + (m_lastCoordinate.Y - coordinate.Y)); 
      } 
      m_lastCoordinate = coordinate; 
     } 
    } 
    private void slideScrollViewer_MouseLeave(object sender, MouseEventArgs e) 
    { 
     m_isCaptured = false; 
     m_lastCoordinate.X = -1; 
    } 
} 
+0

Merci, je ne savais pas que vous pourriez ajouter une classe à un dictionnaire de ressources comme ça. Je ne l'ai pas encore essayé, mais cela devrait fonctionner. – Niki