title: Stop WPF ScrollViewer automatically scrolling to perceived content
body: <p><strong>The Application</strong></p>
  
  <p>I am building an application which includes a range selector. This consists of two custom drawn <code>Slider</code> controls contained within one <code>UserControl</code> derived class. The range selector control is then contained inside a <code>ScrollViewer</code> which has the HorizonalScrollBar visible most of the time.</p>
  
  <p><strong>Sample Application Code:</strong> ( appologies for the wall of text )</p>
  
  <p>Window.xaml  ( the Window file ):</p>
  
  <pre><code>&lt;Grid&gt;
      &lt;ScrollViewer x:Name="ScrollViewer" HorizontalScrollBarVisibility="Visible"  VerticalScrollBarVisibility="Disabled"&gt;
              &lt;local:SliderTest x:Name="slider"                                                                         
                             LowerValue="0"
                             UpperValue="10"
                             Minimum="0"
                             Maximum="100" Width="900" Height="165" Padding="15,0,15,0" HorizontalAlignment="Left"&gt;
              &lt;/local:SliderTest&gt;
      &lt;/ScrollViewer&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p>SliderTest.xaml:</p>
  
  <pre><code>&lt;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"&gt;
      &lt;UserControl.Resources&gt;
          &lt;ControlTemplate x:Key="simpleSlider" TargetType="{x:Type Slider}"&gt;
              &lt;Border SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"&gt;
                  &lt;Grid&gt;
                      &lt;Grid.RowDefinitions&gt;
                          &lt;RowDefinition Height="Auto" /&gt;
                          &lt;RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/&gt;
                          &lt;RowDefinition Height="Auto" /&gt;
                      &lt;/Grid.RowDefinitions&gt;
                      &lt;Track x:Name="PART_Track" Grid.Row="1"&gt;
                          &lt;Track.Thumb&gt;
                              &lt;Thumb x:Name="Thumb" FlowDirection="LeftToRight" Width="15"&gt;
                                  &lt;Thumb.Template&gt;
                                      &lt;ControlTemplate TargetType="Thumb"&gt;
                                          &lt;Canvas&gt;
                                              &lt;Path x:Name="test1" StrokeThickness="0" Fill="DarkGreen"&gt;
                                                  &lt;Path.Data&gt;
                                                      &lt;GeometryGroup FillRule="NonZero"&gt;
                                                          &lt;PathGeometry&gt;
                                                              &lt;PathGeometry.Figures&gt;
                                                                  &lt;PathFigure IsClosed="True" StartPoint="0,150" IsFilled="True"&gt;
                                                                      &lt;PathFigure.Segments&gt;
                                                                          &lt;PathSegmentCollection&gt;
                                                                              &lt;LineSegment Point="-15,150" /&gt;
                                                                              &lt;LineSegment Point="-15,0" /&gt;
                                                                              &lt;LineSegment Point="0,0" /&gt;
                                                                          &lt;/PathSegmentCollection&gt;
                                                                      &lt;/PathFigure.Segments&gt;
                                                                  &lt;/PathFigure&gt;
                                                              &lt;/PathGeometry.Figures&gt;
                                                          &lt;/PathGeometry&gt;
                                                      &lt;/GeometryGroup&gt;
                                                  &lt;/Path.Data&gt;
                                              &lt;/Path&gt;
                                          &lt;/Canvas&gt;
                                      &lt;/ControlTemplate&gt;
                                  &lt;/Thumb.Template&gt;
                              &lt;/Thumb&gt;
                          &lt;/Track.Thumb&gt;
                      &lt;/Track&gt;
                  &lt;/Grid&gt;
              &lt;/Border&gt;
          &lt;/ControlTemplate&gt;
  
          &lt;ControlTemplate x:Key="simpleSliderRight" TargetType="{x:Type Slider}"&gt;
              &lt;Border SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"&gt;
                  &lt;Grid&gt;
                      &lt;Grid.RowDefinitions&gt;
                          &lt;RowDefinition Height="Auto"/&gt;
                          &lt;RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/&gt;
                          &lt;RowDefinition Height="Auto"/&gt;
                      &lt;/Grid.RowDefinitions&gt;
                      &lt;Track x:Name="PART_Track" Grid.Row="1"&gt;
                          &lt;Track.Thumb&gt;
                              &lt;Thumb x:Name="Thumb" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Width="15"&gt;
                                  &lt;Thumb.Template&gt;
                                      &lt;ControlTemplate TargetType="Thumb"&gt;
                                          &lt;Canvas&gt;
                                              &lt;Path Stroke="Black" StrokeThickness="0" Fill="DarkCyan"&gt;
                                                  &lt;Path.Data&gt;
                                                      &lt;GeometryGroup FillRule="NonZero"&gt;
                                                          &lt;PathGeometry&gt;
                                                              &lt;PathGeometry.Figures&gt;
                                                                  &lt;PathFigure IsClosed="True" StartPoint="0,150"&gt;
                                                                      &lt;PathFigure.Segments&gt;
                                                                          &lt;PathSegmentCollection&gt;
                                                                              &lt;LineSegment Point="15,150" /&gt;
                                                                              &lt;LineSegment Point="15,0" /&gt;
                                                                              &lt;LineSegment Point="0,0" /&gt;
                                                                          &lt;/PathSegmentCollection&gt;
                                                                      &lt;/PathFigure.Segments&gt;
                                                                  &lt;/PathFigure&gt;
                                                              &lt;/PathGeometry.Figures&gt;
                                                          &lt;/PathGeometry&gt;
                                                      &lt;/GeometryGroup&gt;
                                                  &lt;/Path.Data&gt;
                                              &lt;/Path&gt;
                                          &lt;/Canvas&gt;
                                      &lt;/ControlTemplate&gt;
                                  &lt;/Thumb.Template&gt;
                              &lt;/Thumb&gt;
                          &lt;/Track.Thumb&gt;
                      &lt;/Track&gt;
                  &lt;/Grid&gt;
              &lt;/Border&gt;
          &lt;/ControlTemplate&gt;
      &lt;/UserControl.Resources&gt;
  
      &lt;Grid x:Name="Gridd" VerticalAlignment="Top" Height="165" &gt;
          &lt;Border x:Name="timeScaleBorder" Width="auto" Height="15" VerticalAlignment="Top" Background="Black"&gt;
              &lt;Canvas x:Name="timeCanvas" Width="auto" Height="15"&gt;
              &lt;/Canvas&gt;
          &lt;/Border&gt;
          &lt;Border x:Name="background" BorderThickness="1,1,1,1" BorderBrush="Black" VerticalAlignment="Center" Height="150"
                  Margin="0,15,0,0" Background="White" /&gt;
          &lt;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" /&gt;
          &lt;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" /&gt;
      &lt;/Grid&gt;
  &lt;/UserControl&gt;
  </code></pre>
  
  <p>SliderText.xaml.cs:</p>
  
  <pre><code>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        
  }
  </code></pre>
  
  <p><strong>The Problem</strong>
  Most of the sample code provided is boring and the mechanics of it works pretty good. The problem I am having is a visual problem specifically with the <code>ScrollViewer</code> control that I have in the main Window. The <code>ScrollViewer</code> seems to be automatically adjusting the horizontal offset of the <code>ScrollViewer</code> when either of the <code>Slider</code>'s gains focus ( from a mouse click for example ).</p>
  
  <p><strong>Reproducing the behaviour</strong></p>
  
  <ol>
  <li>Run the application, you will see that the horizontal scroll bar of the ScrollViewer is visible.</li>
  <li>Click on the Green ( far left ) <code>Slider</code>, you will notice that the ScrollViewer automatically adjusts to shift the horizontal offset to where the perceived 'content' starts.</li>
  </ol>
  
  <p>These symptoms occur at either end of the scroll pane.</p>
  
  <p>Screenshot of application when it is run ( Application is Zoomed in 200% for detail clarity ):</p>
  
  <p><img src="https://i.stack.imgur.com/F33G0.jpg" alt="Screenshot1"></p>
  
  <p>Screenshot of the behavior when the left slider is clicked:</p>
  
  <p><img src="https://i.stack.imgur.com/W844A.jpg" alt="enter image description here"></p>
  
  <p><strong>What I want to happen:</strong></p>
  
  <p>When I click on either slider item ( at either end ) when a slider looks to be beyond end of the slider ( slider range is denoted by the black bar at the top ) I <em>don't</em> want the ScrollViewer to automatically adjust it's horizontal offset.</p>
  
  <p><strong>Suspected problem:</strong></p>
  
  <p>I suspect that the problem is that the ScrollViewer perceives the actual 'content' of it's childen starts 15 pixels ( the drawn width of both of my sliders ) in from where the actual drawn content does start. The Canvas only draws because I included a padding of 15 pixels inside of the <code>SliderTest</code> control on the main window, if this padding is removed the ScrollViewer does not show any of the Slider's Canvas.</p>
  
  <p><strong>EDIT</strong> : it appears the padding is not the problem, read the comments as to why.</p>
  
  <p><strong>Things I have tried</strong></p>
  
  <p>I have tried looking into overriding the OnPreviewMouseDown event of the main Window. The problem here is that I still want both Slider's to behave normally, setting the event to Handled causes the Slider to stop working completely.</p>
  
  <p><strong>Notes:</strong></p>
  
  <p>The Slider's within the range selector control ( Called SliderTest in this example ) must both have a width of 1 pixel. The slider's must be able to extend 15 pixels past the end of the time selection range ( see the black bar at the top for a reference ).</p>
  
  <p>Thank you for reading this novel-lengthed problem.</p>