2010-06-25 111 views
6

我正在尝试制定与WPF滚动条大拇指元素大小相关的算法。设置滚动条缩略大小

可以使用Scrollbar.ViewportSize属性来确定大小元素的大小,但它又与Scrollbar.MinimumScrollbar.Maximum值有关。

我迄今发现的是:

最少和和,的ViewportSize最大:

0 - 拇指最小尺寸
5 - 拇指约25可用轨道的百分比
10 - 大约可用轨道的50%
100 - 大约可用轨道的75%
1000 - 拇指大约90%的可用轨迹
10000 - 拇指填充可用轨迹。

[注:这些数字仅仅是从我粗略的试验和错误]

理想我想能有地方给出的最小值和最大值为滚动我可以设置拇指的算法大小恰好是可用轨道的x%。

任何人都可以帮忙吗?

谢谢。

+0

你不能只从最小值和最大值确定拇指大小的百分比。您还需要相对视口大小(视口中[Min,Max]间隔多少):thumbSizePercent = Min(100,100 * ViewportSize /(MaxValue-MinValue)) – Andy 2010-06-25 08:37:28

回答

11

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

thumbSize = (viewportSize /(最大值 - 最小值+ viewportSize))×径迹

或重新安排viewportSize:

viewportSize = thumbSize×(最大 - 最小)/(trackLength-thumbSize)

您已经发现此问题已经存在,但认为我会发帖以防万一其他人在这里结束。

+1

如果您只需要相对大小:'viewportSize =(最大 - 最小)* p /(1-p)',其中'p'在0.0和1.0之间。 – 2012-03-26 08:48:26

4

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

您可以定义一个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 
} 

}

+2

另一种设置Thumb的MinWidth或MinHeight的方法如下所示:http://msdn.microsoft.com/en-us/library/bb613595.aspx – Kolky 2012-02-08 12:14:24

+0

@Nadzzz:你的代码有很多问题,不会按预期工作。最重要的是,您可以更改ScrollBar的ViewportSize,并且当列表中的项目数发生更改时,将永远不会再计算它。这只适用于静态布局中的静态数据,而不适用于运行时可能会稍微改变的任何内容。 – ygoe 2014-06-11 08:36:42

+0

@Kolky:微软的这个例子也不起作用。它抛出各种例外。我不知道它是否会做正确的事情,如果它工作的话。我看不到任何MinHeight逻辑。 – ygoe 2014-06-11 09:06:37