Wpf 设置滚动条拇指大小

Wpf 设置滚动条拇指大小,wpf,slider,scrollbar,Wpf,Slider,Scrollbar,我正试图找出与WPF滚动条thumb元素大小相关的算法 thumb元素可以使用Scrollbar.ViewportSize属性调整大小,但它又与Scrollbar.Minimum和Scrollbar.Maximum值相关 到目前为止,我发现: 对于0和10的最小值和最大值,视口大小为: 0-拇指最小尺寸 5-拇指大约占可用音轨的25% 10-拇指大约占可用音轨的50% 100-大约75%的可用曲目 1000-拇指大约占可用音轨的90% 10000-拇指填充可用轨迹 [注:这些数字仅来自我的粗略尝

我正试图找出与WPF滚动条thumb元素大小相关的算法

thumb元素可以使用
Scrollbar.ViewportSize
属性调整大小,但它又与
Scrollbar.Minimum
Scrollbar.Maximum
值相关

到目前为止,我发现:

对于010的最小值和最大值,视口大小为:

0-拇指最小尺寸
5-拇指大约占可用音轨的25%
10-拇指大约占可用音轨的50%
100-大约75%的可用曲目
1000-拇指大约占可用音轨的90%
10000-拇指填充可用轨迹

[注:这些数字仅来自我的粗略尝试和错误!]

理想情况下,我希望能够有一个算法,其中给定滚动条的最小值和最大值,我可以将拇指大小设置为可用轨迹的x%

有人能帮忙吗

谢谢。

发件人:

拇指大小= (视口大小/(最大-最小+视口大小))×轨迹长度

或重新安排视口大小:

视口大小= thumbSize×(最大最小)/(轨道长度thumbSize)


你可能已经找到了,但我想我会发布,以防其他人在这里结束。

在我这边,我保留了最小拇指长度,因为触摸输入需要最小尺寸的拇指才能进行触摸优化

您可以定义一个ScrollViewer控件模板,该模板将使用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
}
公共类TouchScrollBar:System.Windows.Controls.Primitives.ScrollBar
{
#区域字段
#区域依赖属性
公共静态只读DependencyProperty MintHumbLength属性=
从属属性。寄存器
((MinThumbLength)、typeof(double)、typeof(TouchScrollBar)、新的UIPropertyMetadata((double)0、OnMinThumbLengthPropertyChanged));
#端区
私人双?m_originalViewportSize;
#端区
#区域属性
公共双倍长度
{
获取{return(double)GetValue(MinThumbLengthProperty);}
set{SetValue(MinThumbLengthProperty,value);}
}
#端区
#区域构造函数
公共触摸工具栏()
{
SizeChanged+=OnSizeChanged;
}
私人布尔穆;
无效OnSizeChanged(对象发送方,SizeChangedEventArgs e)
{
SubscribeTrack();
}
私有无效订阅目录
{
如果(!m_trackSubscribed&&Track!=null)
{
Track.SizeChanged+=OnTrackSizeChanged;
m_=true;
}
}
#端区
#区域保护和私有方法
#区域事件处理程序
#区域依赖属性事件处理程序
MintHumbLengthPropertyChanged上的私有无效(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
TouchScrollBar实例=d作为TouchScrollBar;
if(实例!=null)
{
实例.OnMinThumbLengthChanged(e);
}
}
#端区
受保护的无效OnTrackSizeChanged(对象发送方,SizeChangedEventArgs e)
{
SubscribeTrack();
UpdateViewPort();
}
MaximumChanged上的受保护覆盖无效(双倍旧最大值,双倍新最大值)
{
更改了base.onMaximum(旧最大值、新最大值);
SubscribeTrack();
UpdateViewPort();
}
已更改最小值的受保护覆盖无效值(双倍旧最小值,双倍新最小值)
{
基本最小值已更改(旧最小值、新最小值);
SubscribeTrack();
UpdateViewPort();
}
MintHumbLength更改时受保护的无效(DependencyPropertyChangedEventArgs e)
{
SubscribeTrack();
UpdateViewPort();
}
#端区
私有void UpdateViewPort()
{
如果(磁道!=null)
{
if(m_originalViewportSize==null)
{
m_originalViewportSize=视口大小;
}
双轨迹长度=方向==方向.垂直?轨迹.实际高度:轨迹.实际宽度;
双拇指高度=m_originalViewportSize.Value/(最大-最小+m_originalViewportSize.Value)*轨迹长度;
if(指高

}

如果您正在寻找如何设置滚动条拇指的最小高度:

来自Ian(da real MVP):


或者你知道,添加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;
    }

这里有一个方法,它将覆盖所有
滚动条
s的拇指最小宽度。使用此设置有两个重要原因

1) 这不会调整滚动条的大小。(为什么样式会覆盖
轨迹

2) 这只会调整
滚动条中使用的
轨迹
控件的拇指大小。(为什么
轨迹
样式包含在
滚动条
样式中

<!-- 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>

48
48
48
48

您不能仅从最小值和最大值来确定拇指大小。您还需要相对视口大小(从[Min,Max]间隔到视口的距离):thumbSizePercent=Min(100100*ViewportSize/(MaxValue MinValue))设置MinWidt的另一种方法
<!-- 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>