Arrêter de WPF ScrollViewer automatiquement le défilement de la perception d'un contenu

L'Application

Je suis la construction d'une application qui comprend un sélecteur de plage. Il est composé de deux personnalisé établi Slider contrôles contenus dans un UserControl de la classe dérivée. Le sélecteur de gamme de contrôle est contenue à l'intérieur d'un ScrollViewer qui a le HorizonalScrollBar visible la plupart du temps.

Exemple de Code d'Application: ( appologies pour le mur de texte )

Fenêtre.xaml ( le fichier de la Fenêtre ):

<Grid>
    <ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Visible"  VerticalScrollBarVisibility="Disabled">
            <local:SliderTest x:Name="slider"                                                                         
                           LowerValue="0"
                           UpperValue="10"
                           Minimum="0"
                           Maximum="100" Width="900" Height="165" Padding="15,0,15,0" HorizontalAlignment="Left">
            </local:SliderTest>
    </ScrollViewer>
</Grid>

SliderTest.xaml:

<UserControl x:Class="scrollviewerDemoProblem.SliderTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
x:Name="root"
xmlns:local="clr-namespace:scrollviewerDemoProblem"
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ControlTemplate x:Key="simpleSlider" TargetType="{x:Type Slider}">
<Border SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Track x:Name="PART_Track" Grid.Row="1">
<Track.Thumb>
<Thumb x:Name="Thumb" FlowDirection="LeftToRight" Width="15">
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Canvas>
<Path x:Name="test1" StrokeThickness="0" Fill="DarkGreen">
<Path.Data>
<GeometryGroup FillRule="NonZero">
<PathGeometry>
<PathGeometry.Figures>
<PathFigure IsClosed="True" StartPoint="0,150" IsFilled="True">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="-15,150" />
<LineSegment Point="-15,0" />
<LineSegment Point="0,0" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="simpleSliderRight" TargetType="{x:Type Slider}">
<Border SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Track x:Name="PART_Track" Grid.Row="1">
<Track.Thumb>
<Thumb x:Name="Thumb" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Width="15">
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Canvas>
<Path Stroke="Black" StrokeThickness="0" Fill="DarkCyan">
<Path.Data>
<GeometryGroup FillRule="NonZero">
<PathGeometry>
<PathGeometry.Figures>
<PathFigure IsClosed="True" StartPoint="0,150">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="15,150" />
<LineSegment Point="15,0" />
<LineSegment Point="0,0" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Border>
</ControlTemplate>
</UserControl.Resources>
<Grid x:Name="Gridd" VerticalAlignment="Top" Height="165" >
<Border x:Name="timeScaleBorder" Width="auto" Height="15" VerticalAlignment="Top" Background="Black">
<Canvas x:Name="timeCanvas" Width="auto" Height="15">
</Canvas>
</Border>
<Border x:Name="background" BorderThickness="1,1,1,1" BorderBrush="Black" VerticalAlignment="Center" Height="150"
Margin="0,15,0,0" Background="White" />
<Slider  x:Name="LowerSlider"
Minimum="{Binding ElementName=root, Path=Minimum}"
Maximum="{Binding ElementName=root, Path=Maximum}"
Value="{Binding ElementName=root, Path=LowerValue, Mode=TwoWay}"
Template="{StaticResource simpleSlider}"
Margin="0,15,0,0" />
<Slider  x:Name="UpperSlider"
Minimum="{Binding ElementName=root, Path=Minimum}"
Maximum="{Binding ElementName=root, Path=Maximum}"
Value="{Binding ElementName=root, Path=UpperValue, Mode=TwoWay}"
Template="{StaticResource simpleSliderRight}"
Margin="0,15,0,0" />
</Grid>
</UserControl>

SliderText.xaml.cs:

public partial class SliderTest : UserControl
{
public SliderTest()
{
InitializeComponent();
}
#region Dependency properties, values etc.
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register("Minimum", typeof(double), typeof(SliderTest), new UIPropertyMetadata(0d));
public double LowerValue
{
get { return (double)GetValue(LowerValueProperty); }
set { SetValue(LowerValueProperty, value); }
}
public static readonly DependencyProperty LowerValueProperty =
DependencyProperty.Register("LowerValue", typeof(double), typeof(SliderTest), new UIPropertyMetadata(0d));
public double UpperValue
{
get { return (double)GetValue(UpperValueProperty); }
set { SetValue(UpperValueProperty, value); }
}
public static readonly DependencyProperty UpperValueProperty =
DependencyProperty.Register("UpperValue", typeof(double), typeof(SliderTest), new UIPropertyMetadata(0d));
public double Maximum
{
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(double), typeof(SliderTest), new UIPropertyMetadata(1d));
public double Minimum
{
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
#endregion        
}

Le Problème
La plupart de l'exemple de code fourni est ennuyeux et la mécanique de l', ça fonctionne très bien. Le problème que j'ai est un problème visuel, plus précisément avec l' ScrollViewer de contrôle que j'ai dans la Fenêtre principale. Le ScrollViewer semble être en ajustant automatiquement le décalage horizontal de l' ScrollViewer lorsque l'une des Sliders'obtient le focus ( à partir d'un clic de souris par exemple ).

Reproduisant le comportement

  1. Exécutez l'application, vous verrez que la barre de défilement horizontale de la ScrollViewer est visible.
  2. Cliquez sur le Vert ( à l'extrême gauche ) Slider, vous remarquerez que le ScrollViewer ajuste automatiquement à décalage le décalage horizontal à l'endroit où la perception du 'contenu' commence.

Ces symptômes se produisent à chaque extrémité du panneau défilant.

Capture d'écran de l'application lors de son exécution ( Application est un Zoom de 200% pour le détail des raisons de clarté ):

Arrêter de WPF ScrollViewer automatiquement le défilement de la perception d'un contenu

Capture d'écran du problème lorsque le curseur de gauche est cliqué:

Arrêter de WPF ScrollViewer automatiquement le défilement de la perception d'un contenu

Ce que je veux:

Quand je clique sur chaque curseur de l'élément ( à chaque extrémité ) lorsqu'un curseur qui semble être au-delà de la fin du curseur ( plage du curseur est indiquée par la barre noire en haut ) je ne pas voulez le ScrollViewer pour régler automatiquement le décalage horizontal.

Problème suspecté:

Je soupçonne que le problème est que le ScrollViewer perçoit le réel contenu de ses enfants commence 15 pixels ( la largeur de mes deux curseurs ) à partir de la tiré du contenu de l'démarrer. La Toile tire seulement parce que j'ai inclus un rembourrage de 15 pixels à l'intérieur de la SliderTest de contrôle sur la fenêtre principale, si ce remplissage est retiré, le ScrollViewer ne présentent pas le Curseur de la Toile.

MODIFIER : il semble que le rembourrage n'est pas le problème, lisez les commentaires pourquoi.

Choses que j'ai essayé

J'ai essayé de chercher à passer outre les OnPreviewMouseDown cas de la Fenêtre principale. Le problème, c'est que j'ai encore envie à la fois du Curseur pour se comporter normalement, le réglage de l'événement de traiter des causes le Curseur à cesser de fonctionner complètement.

Notes:

Le Curseur est dans le sélecteur de plage de contrôle ( Appelé SliderTest dans cet exemple ) doivent avoir une largeur de 1 pixel. Le curseur doit être en mesure de prolonger de 15 pixels-delà de la fin du temps de sélection de gamme ( voir la barre noire en haut pour une référence ).

Je vous remercie pour la lecture de ce roman-lengthed problème.

  • +1 pour une question écrite 🙂
  • Cela semble se produire avec tous Sliders, pas seulement votre UserControl. Si vous commentez votre test de curseur et de la remplacer par une horizontale StackPanel contenant un objet comme TextBlock, et un Slider avec un Width tels que les 900, vous obtiendrez le même comportement.
  • Qui est correct.
InformationsquelleAutor user989056 | 2011-12-05