Настройка размера большого пальца полосы прокрутки

Я пытаюсь разработать алгоритм, связанный с размером элемента большого пальца полосы прокрутки WPF.

элемент thumb можно определить размер с помощью Scrollbar.ViewportSize свойство, но оно в свою очередь связано с Scrollbar.Minimum и Scrollbar.Maximum значения.

то, что я обнаружил до сих пор:

для минимума и максимума 0 и 10, а ViewportSize из:

0-Thumb минимальный размер
5-Thumb приблизительно 25% из доступный трек
10-Thumb примерно 50% от доступной дорожки
100-Thumb примерно 75% от доступной дорожки
1000-Thumb примерно 90% доступного трека
10000-Thumb заполняет доступный трек.

[примечание: эти цифры только из моего грубого проб и ошибок!]

В идеале я хотел бы иметь алгоритм, где с учетом минимальных и максимальных значений для полосы прокрутки я могу установить размер большого пальца ровно x% от доступного трека.

может кто-нибудь помочь с этим?

спасибо.

5 ответов


от: http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.track(VS.90).aspx

thumbSize = (viewportSize/(maximum-minimum+viewportSize))×длина дорожки

или перестановка для viewportSize:

viewportSize = thumbSize×(maximum-minimum) / (trackLength-thumbSize)

вы уже нашли это, но думали, что я опубликую, если другие окажутся здесь.


С моей стороны, я сохранил минимальную длину большого пальца, потому что сенсорные входы требуют, чтобы большой палец минимального размера был оптимизирован.

вы можете определить ScrollViewer ControlTemplate, который будет использовать TouchScrollBar в качестве горизонтальной и вертикальной полосы прокрутки.

см. метод 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
}

}


Если вы ищете как установить минимальную высоту ползунком:

от Яна (da real MVP)здесь:

scrollBar1.Track.ViewportSize = double.NaN;  
scrollBar1.Track.Thumb.Height = Math.Max(minThumbHeight, DataScrollBar.Track.Thumb.ActualHeight);

или вы знаете, добавить 100 + строк кода xaml вызывают omgDATABINDING!!1!


размер большого пальца полосы прокрутки для UWP:

    static void SetViewportSize(ScrollBar bar, double size)
    {
        var max = (bar.Maximum - bar.Minimum);
        bar.ViewportSize = size / (max - size) * max;
        bar.IsEnabled = (bar.ViewportSize >= 0 &&
            bar.ViewportSize != double.PositiveInfinity);
        InvalidateScrollBar(bar);
    }

    static void InvalidateScrollBar(ScrollBar bar)
    {
        var v = bar.Value;
        bar.Value = (bar.Value == bar.Maximum) ? bar.Minimum : bar.Maximum;
        bar.Value = v;
    }

вот метод, который переопределит минимальную ширину большого пальца для всех ScrollBars. Есть 2 важные причины для использования этой установки.

1) это не изменит размер ScrollBar RepeatButtons. (Почему стиль переопределяет Track)

2) это только изменить размер больших пальцев для Track элементы управления, которые используются в ScrollBars. (Почему Track стиль содержится в ScrollBar стиль.

<!-- Override for all styles -->
<Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource {x:Type ScrollBar}}">
    <Style.Resources>
        <Style TargetType="{x:Type Track}">
            <Style.Resources>
                <System:Double x:Key="{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}">48</System:Double>
                <System:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}">48</System:Double>
            </Style.Resources>
        </Style>
    </Style.Resources>
</Style>

<!-- Override for a certain control -->
<!-- The ScrollBar Style part in the middle can be safely ommited
if you can guarantee the control only uses Tracks for ScrollBars -->
<SomeControl>
    <SomeControl.Resources>
        <Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource {x:Type ScrollBar}}">
            <Style.Resources>
                <Style TargetType="{x:Type Track}">
                    <Style.Resources>
                        <System:Double x:Key="{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}">48</System:Double>
                        <System:Double x:Key="{x:Static SystemParameters.HorizontalScrollBarButtonWidthKey}">48</System:Double>
                    </Style.Resources>
                </Style>
            </Style.Resources>
        </Style>
    </SomeControl.Resources>
</SomeControl>