Со своей стороны, я сохранил минимальную длину большого пальца, потому что для сенсорного ввода требуется оптимизация большого пальца минимального размера.
Вы можете определить шаблон ScrollViewer ControlTemplate, который будет использовать TouchScrollBar в качестве его горизонтального и вертикальногоScrollBar.
См. Метод UpdateViewPort для математики.
Извините, я не вижу варианта использования для явной установки большого пальца полосы прокрутки для покрытия процента длины дорожки
public class TouchScrollBar : System.Windows.Controls.Primitives.ScrollBar
{
#region Fields
#region Dependency properties
public static readonly DependencyProperty MinThumbLengthProperty =
DependencyProperty.Register
("MinThumbLength", typeof(double), typeof(TouchScrollBar), new UIPropertyMetadata((double)0, OnMinThumbLengthPropertyChanged));
#endregion
private double? m_originalViewportSize;
#endregion
#region Properties
public double MinThumbLength
{
get { return (double)GetValue(MinThumbLengthProperty); }
set { SetValue(MinThumbLengthProperty, value); }
}
#endregion
#region Constructors
public TouchScrollBar()
{
SizeChanged += OnSizeChanged;
}
private bool m_trackSubscribed;
void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
SubscribeTrack();
}
private void SubscribeTrack()
{
if (!m_trackSubscribed && Track != null)
{
Track.SizeChanged += OnTrackSizeChanged;
m_trackSubscribed = true;
}
}
#endregion
#region Protected and private methods
#region Event handlers
#region Dependency properties event handlers
private void OnMinThumbLengthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TouchScrollBar instance = d as TouchScrollBar;
if(instance != null)
{
instance.OnMinThumbLengthChanged(e);
}
}
#endregion
protected void OnTrackSizeChanged(object sender, SizeChangedEventArgs e)
{
SubscribeTrack();
UpdateViewPort();
}
protected override void OnMaximumChanged(double oldMaximum, double newMaximum)
{
base.OnMaximumChanged(oldMaximum, newMaximum);
SubscribeTrack();
UpdateViewPort();
}
protected override void OnMinimumChanged(double oldMinimum, double newMinimum)
{
base.OnMinimumChanged(oldMinimum, newMinimum);
SubscribeTrack();
UpdateViewPort();
}
protected void OnMinThumbLengthChanged(DependencyPropertyChangedEventArgs e)
{
SubscribeTrack();
UpdateViewPort();
}
#endregion
private void UpdateViewPort()
{
if(Track != null)
{
if(m_originalViewportSize == null)
{
m_originalViewportSize = ViewportSize;
}
double trackLength = Orientation == Orientation.Vertical ? Track.ActualHeight : Track.ActualWidth;
double thumbHeight = m_originalViewportSize.Value / (Maximum - Minimum + m_originalViewportSize.Value) * trackLength;
if (thumbHeight < MinThumbLength && !double.IsNaN(thumbHeight))
{
ViewportSize = (MinThumbLength * (Maximum - Minimum)) / (trackLength + MinThumbLength);
}
}
}
#endregion
}
}