Setting the Scrollbar Thumb size

后端 未结 5 1118
醉梦人生
醉梦人生 2021-02-05 17:01

I am attempting to work out the algorithm associated with sizing of the WPF Scrollbar thumb element.

The thumb element can be sized using the Scrollbar.ViewportSi

5条回答
  •  孤独总比滥情好
    2021-02-05 17:30

    On my side, I preserved a minimum thumb length because touch inputs require a thumb of a minimum size to be touch optimized.

    You can define a ScrollViewer ControlTemplate that will use the TouchScrollBar as its horisontal and vertical ScrollBar.

    See UpdateViewPort method for the math.

    Sorry, I don't see the use case for explicitly setting the scrollbar thumb to cover a percentage of the track length

    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
    }
    

    }

提交回复
热议问题