Настройка размера полосы прокрутки - PullRequest
9 голосов
/ 25 июня 2010

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

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

На данный момент я обнаружил:

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

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

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

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

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

Спасибо.

Ответы [ 5 ]

12 голосов
/ 29 сентября 2010

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

thumbSize = (viewportSize / (максимум-минимум + viewportSize)) × trackLength

или переупорядочение для viewportSize:

viewportSize = thumbSize × (максимум-минимум) / (trackLength-thumbSize)

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

4 голосов
/ 25 августа 2011

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

Вы можете определить шаблон 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
}

}

1 голос
/ 03 апреля 2018

Если вы ищете, как установить минимальную высоту для большого пальца полосы прокрутки:

От Иана (да настоящий MVP) здесь :

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

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

0 голосов
/ 17 августа 2018

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

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

2) Это только изменяет размер больших пальцев для Track элементов управления, используемых в ScrollBar с (Почему стиль 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>
0 голосов
/ 24 апреля 2018

Размер большого пальца полосы прокрутки для 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...