De mon côté, j'ai conservé une longueur de pouce minimale car les entrées tactiles nécessitent un pouce d'une taille minimale pour être optimisées pour le toucher.
Vous pouvez définir un ControlTemplate ScrollViewer qui utilisera TouchScrollBar comme sa barre de défilement horizontale et verticale.
Voir la méthode UpdateViewPort pour les calculs.
Désolé, je ne vois pas l'intérêt de définir explicitement la longueur du pouce de la barre de défilement pour couvrir un pourcentage de la longueur de la piste.
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
}
}