ScrollBar.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Framework / System / Windows / Controls / Primitives / ScrollBar.cs / 1 / ScrollBar.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 

using System; 
using System.Collections.Specialized; 
using System.ComponentModel;
using System.Diagnostics; 
using System.Globalization;
using System.Windows.Threading;

using System.Windows; 
using System.Windows.Automation;
using System.Windows.Automation.Peers; 
using System.Windows.Controls; 
using System.Windows.Controls.Primitives;
using System.Windows.Data; 

using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Markup; 

using MS.Internal; 
using MS.Internal.Commands; 
using MS.Internal.KnownBoxes;
using MS.Utility; 
using MS.Internal.Utility;
using MS.Win32;
using System.Security;
using System.Security.Permissions; 

namespace System.Windows.Controls.Primitives 
{ 
    /// 
    ///    ScrollBars are the UI widgets that both let a user drive scrolling from the UI 
    ///    and indicate status of scrolled content.
    ///    These are used inside the ScrollViewer.
    ///    Their visibility is determined by the scroller visibility properties on ScrollViewer.
    ///  
    /// 
    [Localizability(LocalizationCategory.NeverLocalize)] 
    [TemplatePart(Name = "PART_Track", Type = typeof(Track))] 
    public class ScrollBar : RangeBase
    { 
        //-------------------------------------------------------------------
        //
        //  Constructors
        // 
        //-------------------------------------------------------------------
 
        #region Constructors 

        ///  
        /// Instantiates a new instance of a ScrollBar.
        /// 
        public ScrollBar() : base()
        { 
        }
 
 
        #endregion Constructors
 
        //--------------------------------------------------------------------
        //
        //  Public Properties
        // 
        //-------------------------------------------------------------------
 
        #region Public Properties 

        ///  
        ///     Event fires when user press mouse's left button on the thumb.
        /// 
        public static readonly RoutedEvent ScrollEvent = EventManager.RegisterRoutedEvent("Scroll", RoutingStrategy.Bubble, typeof(ScrollEventHandler), typeof(ScrollBar));
 
        /// 
        /// Add / Remove Scroll event handler 
        ///  
        [Category("Behavior")]
        public event ScrollEventHandler Scroll { add { AddHandler(ScrollEvent, value); } remove { RemoveHandler(ScrollEvent, value); } } 

        /// 
        /// This property represents the ScrollBar's : Vertical or Horizontal.
        /// On vertical ScrollBars, the thumb moves up and down.  On horizontal bars, the thumb moves left to right. 
        /// 
        public Orientation Orientation 
        { 
            get { return (Orientation) GetValue(OrientationProperty); }
            set { SetValue(OrientationProperty, value); } 
        }

        /// 
        /// ViewportSize is the amount of the scrolled extent currently visible.  For most scrolled content, this value 
        /// will be bound to one of 's ViewportSize properties.
        /// This property is in logical scrolling units. 
        ///  
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public double ViewportSize 
        {
            get { return (double)GetValue(ViewportSizeProperty); }
            set { SetValue(ViewportSizeProperty, value); }
        } 

        ///  
        /// DependencyProperty for  property. 
        /// 
        public static readonly DependencyProperty OrientationProperty 
            = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(ScrollBar),
                                          new FrameworkPropertyMetadata(Orientation.Vertical),
                                          new ValidateValueCallback(IsValidOrientation));
 

 		///  
        /// DependencyProperty for  property. 
        /// 
        public static readonly DependencyProperty ViewportSizeProperty 
            = DependencyProperty.Register("ViewportSize", typeof(double), typeof(ScrollBar),
                                          new FrameworkPropertyMetadata(0.0d),
                                          new ValidateValueCallback(System.Windows.Shapes.Shape.IsDoubleFiniteNonNegative));
 

        ///  
        /// Gets reference to ScrollBar's Track element. 
        /// 
        public Track Track 
        {
            get
            {
                return _track; 
            }
        } 
 
        #endregion Properties
 
        #region Method Overrides

        /// 
        /// Creates AutomationPeer () 
        /// 
        protected override AutomationPeer OnCreateAutomationPeer() 
        { 
            return new ScrollBarAutomationPeer(this);
        } 

        /// 
        /// ScrollBar supports 'Move-To-Point' by pre-processes Shift+MouseLeftButton Click.
        ///  
        /// 
        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) 
        { 
            _thumbOffset = new Vector();
            if ((Track != null) && 
                (Track.IsMouseOver) &&
                ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift))
            {
                // Move Thumb to the Mouse location 
                Point pt = e.MouseDevice.GetPosition((IInputElement)Track);
                double newValue = Track.ValueFromPoint(pt); 
                if (System.Windows.Shapes.Shape.IsDoubleFinite(newValue)) 
                {
                    ChangeValue(newValue); 
                }

                if (Track.Thumb != null && Track.Thumb.IsMouseOver)
                { 
                    Point thumbPoint = e.MouseDevice.GetPosition((IInputElement)Track.Thumb);
                    _thumbOffset = thumbPoint - new Point(Track.Thumb.ActualWidth * 0.5, Track.Thumb.ActualHeight * 0.5); 
                } 
                else
                { 
                    e.Handled = true;
                }

 

            } 
 
            base.OnPreviewMouseLeftButtonDown(e);
        } 

        /// 
        /// ScrollBar need to remember the point which ContextMenu is invoke in order to perform 'Scroll Here' command correctly.
        ///  
        /// 
        protected override void OnPreviewMouseRightButtonUp(MouseButtonEventArgs e) 
        { 
            if (Track != null)
            { 
                // Remember the mouse point (relative to Track's co-ordinate).
                _latestRightButtonClickPoint = e.MouseDevice.GetPosition((IInputElement)Track);
            }
            else 
            {
                // Clear the mouse point 
                _latestRightButtonClickPoint = new Point(-1,-1); 
            }
 
            base.OnPreviewMouseRightButtonUp(e);
        }

 
        /// 
        ///     Fetches the value of the IsEnabled property 
        ///  
        /// 
        ///     The reason this property is overridden is so that ScrollBar 
        ///     could infuse the value for EnoughContentToScroll into it.
        /// 
        protected override bool IsEnabledCore
        { 
            get
            { 
                return base.IsEnabledCore && _canScroll; 
            }
        } 

        /// 
        /// ScrollBar locates the Track element when its visual tree is created
        ///  
        public override void OnApplyTemplate()
        { 
            base.OnApplyTemplate(); 
            _track = GetTemplateChild(TrackName) as Track;
        } 

        #endregion

        ///  
        /// Scroll content by one line to the top.
        ///  
        public static readonly RoutedCommand LineUpCommand = new RoutedCommand("LineUp", typeof(ScrollBar)); 
        /// 
        /// Scroll content by one line to the bottom. 
        /// 
        public static readonly RoutedCommand LineDownCommand = new RoutedCommand("LineDown", typeof(ScrollBar));
        /// 
        /// Scroll content by one line to the left. 
        /// 
        public static readonly RoutedCommand LineLeftCommand = new RoutedCommand("LineLeft", typeof(ScrollBar)); 
        ///  
        /// Scroll content by one line to the right.
        ///  
        public static readonly RoutedCommand LineRightCommand = new RoutedCommand("LineRight", typeof(ScrollBar));
        /// 
        /// Scroll content by one page to the top.
        ///  
        public static readonly RoutedCommand PageUpCommand = new RoutedCommand("PageUp", typeof(ScrollBar));
        ///  
        /// Scroll content by one page to the bottom. 
        /// 
        public static readonly RoutedCommand PageDownCommand = new RoutedCommand("PageDown", typeof(ScrollBar)); 
        /// 
        /// Scroll content by one page to the left.
        /// 
        public static readonly RoutedCommand PageLeftCommand = new RoutedCommand("PageLeft", typeof(ScrollBar)); 
        /// 
        /// Scroll content by one page to the right. 
        ///  
        public static readonly RoutedCommand PageRightCommand = new RoutedCommand("PageRight", typeof(ScrollBar));
        ///  
        /// Horizontally scroll to the beginning of the content.
        /// 
        public static readonly RoutedCommand ScrollToEndCommand = new RoutedCommand("ScrollToEnd", typeof(ScrollBar));
        ///  
        /// Horizontally scroll to the end of the content.
        ///  
        public static readonly RoutedCommand ScrollToHomeCommand = new RoutedCommand("ScrollToHome", typeof(ScrollBar)); 
        /// 
        /// Horizontally scroll to the beginning of the content. 
        /// 
        public static readonly RoutedCommand ScrollToRightEndCommand = new RoutedCommand("ScrollToRightEnd", typeof(ScrollBar));
        /// 
        /// Horizontally scroll to the end of the content. 
        /// 
        public static readonly RoutedCommand ScrollToLeftEndCommand = new RoutedCommand("ScrollToLeftEnd", typeof(ScrollBar)); 
        ///  
        /// Vertically scroll to the beginning of the content.
        ///  
        public static readonly RoutedCommand ScrollToTopCommand = new RoutedCommand("ScrollToTop", typeof(ScrollBar));
        /// 
        /// Vertically scroll to the end of the content.
        ///  
        public static readonly RoutedCommand ScrollToBottomCommand = new RoutedCommand("ScrollToBottom", typeof(ScrollBar));
        ///  
        /// Scrolls horizontally to the double value provided in . 
        /// 
        public static readonly RoutedCommand ScrollToHorizontalOffsetCommand = new RoutedCommand("ScrollToHorizontalOffset", typeof(ScrollBar)); 
        /// 
        /// Scrolls vertically to the double value provided in .
        /// 
        public static readonly RoutedCommand ScrollToVerticalOffsetCommand = new RoutedCommand("ScrollToVerticalOffset", typeof(ScrollBar)); 

        ///  
        /// Scroll to the point where user invoke ScrollBar ContextMenu.  This command is always handled by ScrollBar. 
        /// 
        public static readonly RoutedCommand ScrollHereCommand = new RoutedCommand("ScrollHere", typeof(ScrollBar)); 


        //--------------------------------------------------------------------
        // 
        //  Private Methods (and Event Handlers)
        // 
        //-------------------------------------------------------------------- 

        #region Private Methods 

        private static void OnThumbDragStarted(object sender, DragStartedEventArgs e)
        {
            ScrollBar scrollBar = sender as ScrollBar; 
            if (scrollBar == null) { return; }
 
            scrollBar._hasScrolled = false; 
            scrollBar._previousValue = scrollBar.Value;
        } 

        // Event handler to listen to thumb events.
        private static void OnThumbDragDelta(object sender, DragDeltaEventArgs e)
        { 
            ScrollBar scrollBar = sender as ScrollBar;
            if (scrollBar == null) { return; } 
 
            scrollBar.UpdateValue(e.HorizontalChange + scrollBar._thumbOffset.X, e.VerticalChange + scrollBar._thumbOffset.Y);
        } 

        // Update ScrollBar Value based on the Thumb drag delta.
        // Deal with pixel -> logical scrolling unit conversion, and restrict the value to within [Minimum, Maximum].
        private void UpdateValue(double horizontalDragDelta, double verticalDragDelta) 
        {
            if (Track != null) 
            { 
                double valueDelta = Track.ValueFromDistance(horizontalDragDelta, verticalDragDelta);
                if (    System.Windows.Shapes.Shape.IsDoubleFinite(valueDelta) 
                    &&  !DoubleUtil.IsZero(valueDelta))
                {
                    double currentValue = Value;
                    double newValue = currentValue + valueDelta; 

                    double perpendicularDragDelta; 
 
                    // Compare distances from thumb for horizontal and vertical orientations
                    if (Orientation == Orientation.Horizontal) 
                    {
                        perpendicularDragDelta = Math.Abs(verticalDragDelta);
                    }
                    else //Orientation == Orientation.Vertical 
                    {
                        perpendicularDragDelta = Math.Abs(horizontalDragDelta); 
                    } 

                    if (DoubleUtil.GreaterThan(perpendicularDragDelta, MaxPerpendicularDelta)) 
                    {
                        newValue = _previousValue;
                    }
 
                    if (!DoubleUtil.AreClose(currentValue, newValue))
                    { 
                        _hasScrolled = true; 
                        ChangeValue(newValue);
                        RaiseScrollEvent(ScrollEventType.ThumbTrack); 
                    }
                }
            }
        } 

        ///  
        /// Listen to Thumb DragCompleted event. 
        /// 
        ///  
        /// 
        private static void OnThumbDragCompleted(object sender, DragCompletedEventArgs e)
        {
            ((ScrollBar)sender).OnThumbDragCompleted(e); 
        }
 
        ///  
        /// Called when user dragging the Thumb.
        /// This function can be override to customize the way Slider handles Thumb movement. 
        /// 
        /// 
        private void OnThumbDragCompleted(DragCompletedEventArgs e)
        { 
            if (_hasScrolled)
            { 
                RaiseScrollEvent(ScrollEventType.EndScroll); 
            }
        } 

        private void ChangeValue(double newValue)
        {
            newValue = Math.Min(Math.Max(newValue, Minimum), Maximum); 
            if (IsStandalone) { Value = newValue; }
            else 
            { 
                IInputElement target = TemplatedParent as IInputElement;
                if (target == null) 
                {
                    target = this;
                }
 
                RoutedCommand command = (Orientation == Orientation.Horizontal) ? ScrollToHorizontalOffsetCommand : ScrollToVerticalOffsetCommand;
                if (command.CanExecute(newValue, target)) 
                { 
                    command.Execute(newValue, target);
                } 
            }
        }

        ///  
        /// Scroll to the position where ContextMenu was invoked.
        ///  
        internal void ScrollToLastMousePoint() 
        {
            Point pt = new Point(-1,-1); 
            if ((Track != null) && (_latestRightButtonClickPoint != pt))
            {
                double newValue = Track.ValueFromPoint(_latestRightButtonClickPoint);
                if (System.Windows.Shapes.Shape.IsDoubleFinite(newValue)) 
                {
                    ChangeValue(newValue); 
                    _latestRightButtonClickPoint = pt; 
                    RaiseScrollEvent(ScrollEventType.ThumbPosition);
                } 
            }
        }

        internal void RaiseScrollEvent(ScrollEventType scrollEventType) 
        {
            ScrollEventArgs newEvent = new ScrollEventArgs(scrollEventType, Value); 
            newEvent.Source=this; 
            RaiseEvent(newEvent);
        } 

        private static void OnScrollCommand(object target, ExecutedRoutedEventArgs args)
        {
            ScrollBar scrollBar = ((ScrollBar)target); 
            if (args.Command == ScrollBar.ScrollHereCommand)
            { 
                scrollBar.ScrollToLastMousePoint(); 
            }
 
            if (scrollBar.IsStandalone)
            {
                if (scrollBar.Orientation == Orientation.Vertical)
                { 
                    if (args.Command == ScrollBar.LineUpCommand)
                    { 
                        scrollBar.LineUp(); 
                    }
                    else if (args.Command == ScrollBar.LineDownCommand) 
                    {
                        scrollBar.LineDown();
                    }
                    else if (args.Command == ScrollBar.PageUpCommand) 
                    {
                        scrollBar.PageUp(); 
                    } 
                    else if (args.Command == ScrollBar.PageDownCommand)
                    { 
                        scrollBar.PageDown();
                    }
                    else if (args.Command == ScrollBar.ScrollToTopCommand)
                    { 
                        scrollBar.ScrollToTop();
                    } 
                    else if (args.Command == ScrollBar.ScrollToBottomCommand) 
                    {
                        scrollBar.ScrollToBottom(); 
                    }
                }
                else //Horizontal
                { 
                    if (args.Command == ScrollBar.LineLeftCommand)
                    { 
                        scrollBar.LineLeft(); 
                    }
                    else if (args.Command == ScrollBar.LineRightCommand) 
                    {
                        scrollBar.LineRight();
                    }
                    else if (args.Command == ScrollBar.PageLeftCommand) 
                    {
                        scrollBar.PageLeft(); 
                    } 
                    else if (args.Command == ScrollBar.PageRightCommand)
                    { 
                        scrollBar.PageRight();
                    }
                    else if (args.Command == ScrollBar.ScrollToLeftEndCommand)
                    { 
                        scrollBar.ScrollToLeftEnd();
                    } 
                    else if (args.Command == ScrollBar.ScrollToRightEndCommand) 
                    {
                        scrollBar.ScrollToRightEnd(); 
                    }
                }
            }
        } 

        private void SmallDecrement() 
        { 
            double newValue = Math.Max(Value - SmallChange, Minimum);
            if (Value != newValue) 
            {
                Value = newValue;
                RaiseScrollEvent(ScrollEventType.SmallDecrement);
            } 
        }
        private void SmallIncrement() 
        { 
            double newValue = Math.Min(Value + SmallChange, Maximum);
            if (Value != newValue) 
            {
                Value = newValue;
                RaiseScrollEvent(ScrollEventType.SmallIncrement);
            } 
        }
        private void LargeDecrement() 
        { 
            double newValue = Math.Max(Value - LargeChange, Minimum);
            if (Value != newValue) 
            {
                Value = newValue;
                RaiseScrollEvent(ScrollEventType.LargeDecrement);
            } 
        }
        private void LargeIncrement() 
        { 
            double newValue = Math.Min(Value + LargeChange, Maximum);
            if (Value != newValue) 
            {
                Value = newValue;
                RaiseScrollEvent(ScrollEventType.LargeIncrement);
            } 
        }
        private void ToMinimum() 
        { 
            if (Value != Minimum)
            { 
                Value = Minimum;
                RaiseScrollEvent(ScrollEventType.First);
            }
        } 
        private void ToMaximum()
        { 
            if (Value != Maximum) 
            {
                Value = Maximum; 
                RaiseScrollEvent(ScrollEventType.Last);
            }
        }
        private void LineUp() 
        {
            SmallDecrement(); 
        } 
        private void LineDown()
        { 
            SmallIncrement();
        }
        private void PageUp()
        { 
            LargeDecrement();
        } 
        private void PageDown() 
        {
            LargeIncrement(); 
        }
        private void ScrollToTop()
        {
            ToMinimum(); 
        }
        private void ScrollToBottom() 
        { 
            ToMaximum();
        } 
        private void LineLeft()
        {
            SmallDecrement();
        } 
        private void LineRight()
        { 
            SmallIncrement(); 
        }
        private void PageLeft() 
        {
            LargeDecrement();
        }
        private void PageRight() 
        {
            LargeIncrement(); 
        } 
        private void ScrollToLeftEnd()
        { 
            ToMinimum();
        }
        private void ScrollToRightEnd()
        { 
            ToMaximum();
        } 
 
        private static void OnQueryScrollHereCommand(object target, CanExecuteRoutedEventArgs args)
        { 
            args.CanExecute = (args.Command == ScrollBar.ScrollHereCommand);
        }

        private static void OnQueryScrollCommand(object target, CanExecuteRoutedEventArgs args) 
        {
            args.CanExecute = ((ScrollBar)target).IsStandalone; 
        } 

        #endregion 

        //-------------------------------------------------------------------
        //
        //  Private Members 
        //
        //-------------------------------------------------------------------- 
 
        #region Private Members
 
        #endregion

        //-------------------------------------------------------------------
        // 
        //  Static Constructor & Delegates
        // 
        //------------------------------------------------------------------- 

        #region Static Constructor & Delegates 

        static ScrollBar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(typeof(ScrollBar))); 
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(ScrollBar));
 
            FocusableProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox)); 

            // Register Event Handler for the Thumb 
            EventManager.RegisterClassHandler(typeof(ScrollBar), Thumb.DragStartedEvent, new DragStartedEventHandler(OnThumbDragStarted));
            EventManager.RegisterClassHandler(typeof(ScrollBar), Thumb.DragDeltaEvent, new DragDeltaEventHandler(OnThumbDragDelta));
            EventManager.RegisterClassHandler(typeof(ScrollBar), Thumb.DragCompletedEvent, new DragCompletedEventHandler(OnThumbDragCompleted));
 
            // ScrollBar has common handler for ScrollHere command.
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.ScrollHereCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollHereCommand)); 
            // Vertical Commands 
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.LineUpCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.Up));
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.LineDownCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.Down)); 
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.PageUpCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.PageUp));
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.PageDownCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.PageDown));
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.ScrollToTopCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.Home, ModifierKeys.Control));
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.ScrollToBottomCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.End, ModifierKeys.Control)); 
            // Horizontal Commands
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.LineLeftCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.Left)); 
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.LineRightCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.Right)); 
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.PageLeftCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand));
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.PageRightCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand)); 
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.ScrollToLeftEndCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.Home));
            CommandHelpers.RegisterCommandHandler(typeof(ScrollBar), ScrollBar.ScrollToRightEndCommand, new ExecutedRoutedEventHandler(OnScrollCommand), new CanExecuteRoutedEventHandler(OnQueryScrollCommand), new KeyGesture(Key.End));

            MaximumProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(new PropertyChangedCallback(ViewChanged))); 
            MinimumProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(new PropertyChangedCallback(ViewChanged)));
 
            ContextMenuProperty.OverrideMetadata(typeof(ScrollBar), new FrameworkPropertyMetadata(null, new CoerceValueCallback(CoerceContextMenu))); 
        }
 
        private static void ViewChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ScrollBar scrollBar = (ScrollBar)d;
 
            bool canScrollNew = scrollBar.Maximum > scrollBar.Minimum;
 
            if (canScrollNew != scrollBar._canScroll) 
            {
                scrollBar._canScroll = canScrollNew; 
                scrollBar.CoerceValue(IsEnabledProperty);
            }
        }
 
        // Consider adding a verify for ViewportSize to check > 0.0
 
        internal static bool IsValidOrientation(object o) 
        {
            Orientation value = (Orientation)o; 
            return value == Orientation.Horizontal
                || value == Orientation.Vertical;
        }
 
        // Is the scrollbar outside of a scrollviewer?
        internal bool IsStandalone 
        { 
            get { return _isStandalone; }
            set { _isStandalone = value; } 
        }

        // Maximum distance you can drag from thumb before it snaps back
        private const double MaxPerpendicularDelta = 150; 
        private const string TrackName = "PART_Track";
 
        private Track _track; 

        private Point _latestRightButtonClickPoint = new Point(-1,-1); 

        private bool _canScroll = true;  // Maximum > Minimum by default
        private bool _hasScrolled;  // Has the thumb been dragged
        private bool _isStandalone = true; 
        private bool _openingContextMenu;
        private double _previousValue; 
        private Vector _thumbOffset; 

 

        #endregion

 
        #region DTypeThemeStyleKey
 
        // Returns the DependencyObjectType for the registered ThemeStyleKey's default 
        // value. Controls will override this method to return approriate types.
        internal override DependencyObjectType DTypeThemeStyleKey 
        {
            get { return _dType; }
        }
 
        private static DependencyObjectType _dType;
 
        #endregion DTypeThemeStyleKey 

        #region ContextMenu 

        private static object CoerceContextMenu(DependencyObject o, object value)
        {
            bool hasModifiers; 
            ScrollBar sb = (ScrollBar)o;
            if (sb._openingContextMenu && 
                sb.GetValueSource(ContextMenuProperty, null, out hasModifiers) == BaseValueSourceInternal.Default && !hasModifiers) 
            {
                // Use a default menu 
                if (sb.Orientation == Orientation.Vertical)
                {
                    return VerticalContextMenu;
                } 
                else if (sb.FlowDirection == FlowDirection.LeftToRight)
                { 
                    return HorizontalContextMenuLTR; 
                }
                else 
                {
                    return HorizontalContextMenuRTL;
                }
            } 
            return value;
        } 
 
        /// 
        ///     Called when ContextMenuOpening is raised on this element. 
        /// 
        /// Event arguments
        protected override void OnContextMenuOpening(ContextMenuEventArgs e)
        { 
            base.OnContextMenuOpening(e);
 
            if (!e.Handled) 
            {
                _openingContextMenu = true; 
                CoerceValue(ContextMenuProperty);
            }
        }
 
        /// 
        ///     Called when ContextMenuOpening is raised on this element. 
        ///  
        /// Event arguments
        protected override void OnContextMenuClosing(ContextMenuEventArgs e) 
        {
            base.OnContextMenuClosing(e);

            _openingContextMenu = false; 
            CoerceValue(ContextMenuProperty);
        } 
 
        private static ContextMenu VerticalContextMenu
        { 
            get
            {
                ContextMenu verticalContextMenu = new ContextMenu();
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollHere, "ScrollHere", ScrollBar.ScrollHereCommand)); 
                verticalContextMenu.Items.Add(new Separator());
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_Top, "Top", ScrollBar.ScrollToTopCommand)); 
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_Bottom, "Bottom", ScrollBar.ScrollToBottomCommand)); 
                verticalContextMenu.Items.Add(new Separator());
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageUp, "PageUp", ScrollBar.PageUpCommand)); 
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageDown, "PageDown", ScrollBar.PageDownCommand));
                verticalContextMenu.Items.Add(new Separator());
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollUp, "ScrollUp", ScrollBar.LineUpCommand));
                verticalContextMenu.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollDown, "ScrollDown", ScrollBar.LineDownCommand)); 
                return verticalContextMenu;
            } 
        } 

        // LeftToRight menu 
        private static ContextMenu HorizontalContextMenuLTR
        {
            get
            { 
                ContextMenu horizontalContextMenuLeftToRight = new ContextMenu();
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollHere, "ScrollHere", ScrollBar.ScrollHereCommand)); 
                horizontalContextMenuLeftToRight.Items.Add(new Separator()); 
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_LeftEdge, "LeftEdge", ScrollBar.ScrollToLeftEndCommand));
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_RightEdge, "RightEdge", ScrollBar.ScrollToRightEndCommand)); 
                horizontalContextMenuLeftToRight.Items.Add(new Separator());
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageLeft, "PageLeft", ScrollBar.PageLeftCommand));
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageRight, "PageRight", ScrollBar.PageRightCommand));
                horizontalContextMenuLeftToRight.Items.Add(new Separator()); 
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollLeft, "ScrollLeft", ScrollBar.LineLeftCommand));
                horizontalContextMenuLeftToRight.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollRight, "ScrollRight", ScrollBar.LineRightCommand)); 
                return horizontalContextMenuLeftToRight; 
            }
        } 

        // RightToLeft menu
        private static ContextMenu HorizontalContextMenuRTL
        { 
            get
            { 
                ContextMenu horizontalContextMenuRightToLeft = new ContextMenu(); 
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollHere, "ScrollHere", ScrollBar.ScrollHereCommand));
                horizontalContextMenuRightToLeft.Items.Add(new Separator()); 
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_LeftEdge, "LeftEdge", ScrollBar.ScrollToRightEndCommand));
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_RightEdge, "RightEdge", ScrollBar.ScrollToLeftEndCommand));
                horizontalContextMenuRightToLeft.Items.Add(new Separator());
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageLeft, "PageLeft", ScrollBar.PageRightCommand)); 
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_PageRight, "PageRight", ScrollBar.PageLeftCommand));
                horizontalContextMenuRightToLeft.Items.Add(new Separator()); 
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollLeft, "ScrollLeft", ScrollBar.LineRightCommand)); 
                horizontalContextMenuRightToLeft.Items.Add(CreateMenuItem(SRID.ScrollBar_ContextMenu_ScrollRight, "ScrollRight", ScrollBar.LineLeftCommand));
                return horizontalContextMenuRightToLeft; 
            }
        }

        private static MenuItem CreateMenuItem(SRID name, string automationId, RoutedCommand command) 
        {
            MenuItem menuItem = new MenuItem(); 
            menuItem.Header = SR.Get(name); 
            menuItem.Command = command;
            AutomationProperties.SetAutomationId(menuItem, automationId); 

            Binding binding = new Binding();
            binding.Path = new PropertyPath(ContextMenu.PlacementTargetProperty);
            binding.Mode = BindingMode.OneWay; 
            binding.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ContextMenu), 1);
            menuItem.SetBinding(MenuItem.CommandTargetProperty, binding); 
 
            return menuItem;
        } 

        //
        //  This property
        //  1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject 
        //  2. This is a performance optimization
        // 
        internal override int EffectiveValuesInitialSize 
        {
            get { return 42; } 
        }

        #endregion ContextMenu
    } 

    ///  
    /// Type of scrolling that causes ScrollEvent. 
    /// 
    public enum ScrollEventType 
    {
        /// 
        /// Thumb has stopped moving.
        ///  
        EndScroll,
        ///  
        /// Thumb was moved to the Minimum position. 
        /// 
        First, 
        /// 
        /// Thumb was moved a large distance. The user clicked the scroll bar to the left(horizontal) or above(vertical) the scroll box.
        /// 
        LargeDecrement, 
        /// 
        /// Thumb was moved a large distance. The user clicked the scroll bar to the right(horizontal) or below(vertical) the scroll box. 
        ///  
        LargeIncrement,
        ///  
        /// Thumb was moved to the Maximum position
        /// 
        Last,
        ///  
        /// Thumb was moved a small distance. The user clicked the left(horizontal) or top(vertical) scroll arrow.
        ///  
        SmallDecrement, 
        /// 
        /// Thumb was moved a small distance. The user clicked the right(horizontal) or bottom(vertical) scroll arrow. 
        /// 
        SmallIncrement,
        /// 
        /// Thumb was moved. 
        /// 
        ThumbPosition, 
        ///  
        /// Thumb is currently being moved.
        ///  
        ThumbTrack
    }

} 

 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK