1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004 Novell, Inc.
23 // Peter Bartok pbartok@novell.com
27 using System
.ComponentModel
;
28 using System
.ComponentModel
.Design
;
30 using System
.Runtime
.InteropServices
;
32 namespace System
.Windows
.Forms
{
33 [Designer ("System.Windows.Forms.Design.ScrollableControlDesigner, " + Consts
.AssemblySystem_Design
, "System.ComponentModel.Design.IDesigner")]
35 [ClassInterface (ClassInterfaceType
.AutoDispatch
)]
38 public class ScrollableControl
: Control
{
39 #region Local Variables
40 private bool force_hscroll_visible
;
41 private bool force_vscroll_visible
;
42 private bool auto_scroll
;
43 private Size auto_scroll_margin
;
44 private Size auto_scroll_min_size
;
45 private Point scroll_position
;
46 private DockPaddingEdges dock_padding
;
47 private SizeGrip sizegrip
;
48 private ImplicitHScrollBar hscrollbar
;
49 private ImplicitVScrollBar vscrollbar
;
50 private Size canvas_size
;
51 private Rectangle display_rectangle
;
52 private Control old_parent
;
53 #endregion // Local Variables
55 [TypeConverter(typeof(ScrollableControl
.DockPaddingEdgesConverter
))]
56 #region Subclass DockPaddingEdges
57 public class DockPaddingEdges
: ICloneable
{
58 #region DockPaddingEdges Local Variables
64 private Control owner
;
65 #endregion // DockPaddingEdges Local Variables
67 #region DockPaddingEdges Constructor
68 internal DockPaddingEdges(Control owner
) {
76 #endregion // DockPaddingEdges Constructor
78 #region DockPaddingEdges Public Instance Properties
79 [RefreshProperties(RefreshProperties
.All
)]
92 owner
.PerformLayout();
96 [RefreshProperties(RefreshProperties
.All
)]
106 owner
.PerformLayout();
110 [RefreshProperties(RefreshProperties
.All
)]
120 owner
.PerformLayout();
124 [RefreshProperties(RefreshProperties
.All
)]
134 owner
.PerformLayout();
138 [RefreshProperties(RefreshProperties
.All
)]
148 owner
.PerformLayout();
151 #endregion // DockPaddingEdges Public Instance Properties
153 // Public Instance Methods
154 public override bool Equals(object other
) {
155 if (! (other
is DockPaddingEdges
)) {
159 if ( (this.all
== ((DockPaddingEdges
)other
).all
) && (this.left
== ((DockPaddingEdges
)other
).left
) &&
160 (this.right
== ((DockPaddingEdges
)other
).right
) && (this.top
== ((DockPaddingEdges
)other
).top
) &&
161 (this.bottom
== ((DockPaddingEdges
)other
).bottom
)) {
168 public override int GetHashCode() {
169 return all
*top
*bottom
*right
*left
;
172 public override string ToString() {
173 return "All = "+all
.ToString()+" Top = "+top
.ToString()+" Left = "+left
.ToString()+" Bottom = "+bottom
.ToString()+" Right = "+right
.ToString();
176 internal void Scale(float dx
, float dy
) {
177 left
= (int) (left
* dx
);
178 right
= (int) (right
* dx
);
179 top
= (int) (top
* dy
);
180 bottom
= (int) (bottom
* dy
);
183 object ICloneable
.Clone() {
184 DockPaddingEdges padding_edge
;
186 padding_edge
=new DockPaddingEdges(owner
);
188 padding_edge
.all
=all
;
189 padding_edge
.left
=left
;
190 padding_edge
.right
=right
;
191 padding_edge
.top
=top
;
192 padding_edge
.bottom
=bottom
;
197 #endregion // Subclass DockPaddingEdges
199 #region Subclass DockPaddingEdgesConverter
200 public class DockPaddingEdgesConverter
: System
.ComponentModel
.TypeConverter
{
201 // Public Constructors
202 public DockPaddingEdgesConverter() {
205 // Public Instance Methods
206 public override PropertyDescriptorCollection
GetProperties(System
.ComponentModel
.ITypeDescriptorContext context
, object value, Attribute
[] attributes
) {
207 return TypeDescriptor
.GetProperties(typeof(DockPaddingEdges
), attributes
);
210 public override bool GetPropertiesSupported(System
.ComponentModel
.ITypeDescriptorContext context
) {
214 #endregion // Subclass DockPaddingEdgesConverter
216 #region Public Constructors
217 public ScrollableControl() {
218 SetStyle(ControlStyles
.ContainerControl
, true);
219 SetStyle(ControlStyles
.AllPaintingInWmPaint
, false);
222 force_hscroll_visible
= false;
223 force_vscroll_visible
= false;
224 auto_scroll_margin
= new Size(0, 0);
225 auto_scroll_min_size
= new Size(0, 0);
226 scroll_position
= new Point(0, 0);
227 dock_padding
= new DockPaddingEdges(this);
228 SizeChanged
+=new EventHandler(Recalculate
);
229 VisibleChanged
+= new EventHandler(Recalculate
);
230 LocationChanged
+= new EventHandler (LocationChangedHandler
);
231 ParentChanged
+= new EventHandler (ParentChangedHandler
);
236 void LocationChangedHandler (object sender
, EventArgs e
)
238 UpdateSizeGripVisible ();
241 void ParentChangedHandler (object sender
, EventArgs e
)
244 if (old_parent
== Parent
)
247 if (old_parent
!= null) {
248 old_parent
.SizeChanged
-= new EventHandler (Parent_SizeChanged
);
250 old_parent
.PaddingChanged
-= new EventHandler (Parent_PaddingChanged
);
254 if (Parent
!= null) {
255 Parent
.SizeChanged
+= new EventHandler (Parent_SizeChanged
);
257 Parent
.PaddingChanged
+= new EventHandler (Parent_PaddingChanged
);
264 void Parent_PaddingChanged (object sender
, EventArgs e
)
266 UpdateSizeGripVisible ();
269 void Parent_SizeChanged (object sender
, EventArgs e
)
271 UpdateSizeGripVisible ();
273 #endregion // Public Constructors
275 #region Protected Static Fields
276 protected const int ScrollStateAutoScrolling
= 1;
277 protected const int ScrollStateFullDrag
= 16;
278 protected const int ScrollStateHScrollVisible
= 2;
279 protected const int ScrollStateUserHasScrolled
= 8;
280 protected const int ScrollStateVScrollVisible
= 4;
281 #endregion // Protected Static Fields
283 #region Public Instance Properties
284 [DefaultValue(false)]
286 [MWFCategory("Layout")]
287 public virtual bool AutoScroll
{
293 if (auto_scroll
== value) {
302 [MWFCategory("Layout")]
303 public Size AutoScrollMargin
{
305 return auto_scroll_margin
;
309 if (value.Width
< 0) {
310 throw new ArgumentException("Width is assigned less than 0", "value.Width");
313 if (value.Height
< 0) {
314 throw new ArgumentException("Height is assigned less than 0", "value.Height");
317 auto_scroll_margin
= value;
322 [MWFCategory("Layout")]
323 public Size AutoScrollMinSize
{
325 return auto_scroll_min_size
;
329 if (value != auto_scroll_min_size
) {
330 auto_scroll_min_size
= value;
337 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
338 public Point AutoScrollPosition
{
340 return new Point(-scroll_position
.X
, -scroll_position
.Y
);
344 if ((value.X
!= scroll_position
.X
) || (value.Y
!= scroll_position
.Y
)) {
350 if (hscrollbar
.VisibleInternal
) {
351 shift_x
= value.X
- scroll_position
.X
;
354 if (vscrollbar
.VisibleInternal
) {
355 shift_y
= value.Y
- scroll_position
.Y
;
358 ScrollWindow(shift_x
, shift_y
);
360 if (hscrollbar
.VisibleInternal
) {
361 hscrollbar
.Value
= scroll_position
.X
;
364 if (vscrollbar
.VisibleInternal
) {
365 vscrollbar
.Value
= scroll_position
.Y
;
372 public override Rectangle DisplayRectangle
{
378 if (canvas_size
.Width
<= base.DisplayRectangle
.Width
) {
379 width
= base.DisplayRectangle
.Width
;
380 if (vscrollbar
.VisibleInternal
) {
381 width
-= vscrollbar
.Width
;
384 width
= canvas_size
.Width
;
387 if (canvas_size
.Height
<= base.DisplayRectangle
.Height
) {
388 height
= base.DisplayRectangle
.Height
;
389 if (hscrollbar
.VisibleInternal
) {
390 height
-= hscrollbar
.Height
;
393 height
= canvas_size
.Height
;
396 display_rectangle
.X
= -scroll_position
.X
;
397 display_rectangle
.Y
= -scroll_position
.Y
;
398 display_rectangle
.Width
= Math
.Max(auto_scroll_min_size
.Width
, width
);
399 display_rectangle
.Height
= Math
.Max(auto_scroll_min_size
.Height
, height
);
402 display_rectangle
= base.DisplayRectangle
;
405 display_rectangle
.X
+= dock_padding
.Left
;
406 display_rectangle
.Y
+= dock_padding
.Top
;
407 display_rectangle
.Width
-= dock_padding
.Left
+ dock_padding
.Right
;
408 display_rectangle
.Height
-= dock_padding
.Top
+ dock_padding
.Bottom
;
410 return display_rectangle
;
414 [MWFCategory("Layout")]
417 [EditorBrowsable (EditorBrowsableState
.Never
)]
418 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
420 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
)]
423 public DockPaddingEdges DockPadding
{
428 #endregion // Public Instance Properties
430 #region Protected Instance Methods
431 protected override CreateParams CreateParams
{
433 return base.CreateParams
;
437 protected bool HScroll
{
439 return hscrollbar
.VisibleInternal
;
443 if (hscrollbar
.VisibleInternal
!= value) {
444 force_hscroll_visible
= value;
445 Recalculate(this, EventArgs
.Empty
);
450 protected bool VScroll
{
452 return vscrollbar
.VisibleInternal
;
456 if (vscrollbar
.VisibleInternal
!= value) {
457 force_vscroll_visible
= value;
458 Recalculate(this, EventArgs
.Empty
);
462 #endregion // Protected Instance Methods
464 #region Public Instance Methods
465 public void ScrollControlIntoView(Control activeControl
) {
471 if (!AutoScroll
|| (!hscrollbar
.VisibleInternal
&& !vscrollbar
.VisibleInternal
)) {
475 if (!Contains(activeControl
)) {
479 x
= activeControl
.Left
;
480 y
= activeControl
.Top
;
482 // Translate into coords relative to us
483 if (activeControl
.Parent
!= this) {
484 activeControl
.PointToScreen(ref x
, ref y
);
485 PointToClient(ref x
, ref y
);
488 x
+= scroll_position
.X
;
489 y
+= scroll_position
.Y
;
491 // Don't scroll if already visible
492 if ((activeControl
.Left
>= scroll_position
.X
) && (activeControl
.Left
< (scroll_position
.X
+ ClientSize
.Width
)) &&
493 (activeControl
.Top
>= scroll_position
.Y
) && (activeControl
.Top
< (scroll_position
.Y
+ ClientSize
.Height
))) {
498 corner_x
= Math
.Max(0, x
+ activeControl
.Width
/ 2 - ClientSize
.Width
/ 2);
499 corner_y
= Math
.Max(0, y
+ activeControl
.Height
/ 2 - ClientSize
.Height
/ 2);
501 if (hscrollbar
.VisibleInternal
&& (corner_x
> hscrollbar
.Maximum
)) {
502 corner_x
= Math
.Max(0, hscrollbar
.Maximum
- ClientSize
.Width
);
505 if (vscrollbar
.VisibleInternal
&& (corner_y
> vscrollbar
.Maximum
)) {
506 corner_y
= Math
.Max(0, vscrollbar
.Maximum
- ClientSize
.Height
);
508 if ((corner_x
== scroll_position
.X
) && (corner_y
== scroll_position
.Y
)) {
512 //this.SetDisplayRectLocation(-corner_x, -corner_y);
513 hscrollbar
.Value
= corner_x
;
514 vscrollbar
.Value
= corner_y
;
517 public void SetAutoScrollMargin(int x
, int y
) {
526 auto_scroll_margin
= new Size(x
, y
);
527 Recalculate(this, EventArgs
.Empty
);
529 #endregion // Public Instance Methods
531 #region Protected Instance Methods
532 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
533 protected virtual void AdjustFormScrollbars(bool displayScrollbars
) {
534 Recalculate(this, EventArgs
.Empty
);
537 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
538 protected bool GetScrollState(int bit
) {
543 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
544 protected override void OnLayout(LayoutEventArgs levent
) {
545 CalculateCanvasSize();
547 AdjustFormScrollbars(AutoScroll
); // Dunno what the logic is. Passing AutoScroll seems to match MS behaviour
548 base.OnLayout(levent
);
551 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
552 protected override void OnMouseWheel(MouseEventArgs e
) {
553 if (vscrollbar
.VisibleInternal
) {
555 if (vscrollbar
.Minimum
< (vscrollbar
.Value
- vscrollbar
.LargeChange
)) {
556 vscrollbar
.Value
-= vscrollbar
.LargeChange
;
558 vscrollbar
.Value
= vscrollbar
.Minimum
;
561 int maximum_scrollbar_value
= vscrollbar
.Maximum
- vscrollbar
.LargeChange
+ 1;
562 if (maximum_scrollbar_value
> (vscrollbar
.Value
+ vscrollbar
.LargeChange
)) {
563 vscrollbar
.Value
+= vscrollbar
.LargeChange
;
565 vscrollbar
.Value
= maximum_scrollbar_value
;
569 base.OnMouseWheel(e
);
572 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
573 protected override void OnVisibleChanged(EventArgs e
) {
575 UpdateChildrenZOrder ();
578 base.OnVisibleChanged(e
);
582 [EditorBrowsable (EditorBrowsableState
.Never
)]
584 protected override void ScaleCore(float dx
, float dy
) {
585 dock_padding
.Scale(dx
, dy
);
586 base.ScaleCore(dx
, dy
);
589 protected void SetDisplayRectLocation(int x
, int y
) {
590 // This method is weird. MS documents that the scrollbars are not
591 // updated. We need to move stuff, but leave the scrollbars as is
601 ScrollWindow(scroll_position
.X
- x
, scroll_position
.Y
- y
);
604 protected void SetScrollState(int bit
, bool value) {
605 //throw new NotImplementedException();
608 [EditorBrowsable(EditorBrowsableState
.Advanced
)]
609 protected override void WndProc(ref Message m
) {
612 #endregion // Protected Instance Methods
614 #region Internal & Private Methods
615 private void CalculateCanvasSize() {
623 num_of_children
= Controls
.Count
;
626 extra_width
= dock_padding
.Right
;
627 extra_height
= dock_padding
.Bottom
;
629 for (int i
= 0; i
< num_of_children
; i
++) {
631 if (child
.Dock
== DockStyle
.Right
) {
632 extra_width
+= child
.Width
;
633 } else if (child
.Dock
== DockStyle
.Bottom
) {
634 extra_height
+= child
.Height
;
638 if (!auto_scroll_min_size
.IsEmpty
) {
639 width
= auto_scroll_min_size
.Width
;
640 height
= auto_scroll_min_size
.Height
;
643 for (int i
= 0; i
< num_of_children
; i
++) {
647 case DockStyle
.Left
: {
648 if ((child
.Right
+ extra_width
) > width
) {
649 width
= child
.Right
+ extra_width
;
654 case DockStyle
.Top
: {
655 if ((child
.Bottom
+ extra_height
) > height
) {
656 height
= child
.Bottom
+ extra_height
;
662 case DockStyle
.Right
:
663 case DockStyle
.Bottom
: {
670 anchor
= child
.Anchor
;
672 if (((anchor
& AnchorStyles
.Left
) != 0) && ((anchor
& AnchorStyles
.Right
) == 0)) {
673 if ((child
.Right
+ extra_width
) > width
) {
674 width
= child
.Right
+ extra_width
;
678 if (((anchor
& AnchorStyles
.Top
) != 0) || ((anchor
& AnchorStyles
.Bottom
) == 0)) {
679 if ((child
.Bottom
+ extra_height
) > height
) {
680 height
= child
.Bottom
+ extra_height
;
687 width
+= scroll_position
.X
;
688 height
+= scroll_position
.Y
;
690 canvas_size
.Width
= width
;
691 canvas_size
.Height
= height
;
694 private void Recalculate (object sender
, EventArgs e
) {
695 if (!IsHandleCreated
) {
699 Size canvas
= canvas_size
;
700 Size client
= ClientSize
;
702 canvas
.Width
+= auto_scroll_margin
.Width
;
703 canvas
.Height
+= auto_scroll_margin
.Height
;
705 int right_edge
= client
.Width
;
706 int bottom_edge
= client
.Height
;
708 int prev_bottom_edge
;
710 bool hscroll_visible
;
711 bool vscroll_visible
;
714 prev_right_edge
= right_edge
;
715 prev_bottom_edge
= bottom_edge
;
717 if ((force_hscroll_visible
|| canvas
.Width
> right_edge
) && client
.Width
> 0) {
718 hscroll_visible
= true;
719 bottom_edge
= client
.Height
- SystemInformation
.HorizontalScrollBarHeight
;
721 hscroll_visible
= false;
722 bottom_edge
= client
.Height
;
725 if ((force_vscroll_visible
|| canvas
.Height
> bottom_edge
) && client
.Height
> 0) {
726 vscroll_visible
= true;
727 right_edge
= client
.Width
- SystemInformation
.VerticalScrollBarWidth
;
729 vscroll_visible
= false;
730 right_edge
= client
.Width
;
733 } while (right_edge
!= prev_right_edge
|| bottom_edge
!= prev_bottom_edge
);
735 if (right_edge
< 0) right_edge
= 0;
736 if (bottom_edge
< 0) bottom_edge
= 0;
738 Rectangle hscroll_bounds
;
739 Rectangle vscroll_bounds
;
741 hscroll_bounds
= new Rectangle (0, client
.Height
- SystemInformation
.HorizontalScrollBarHeight
,
742 ClientRectangle
.Width
, SystemInformation
.HorizontalScrollBarHeight
);
743 vscroll_bounds
= new Rectangle (client
.Width
- SystemInformation
.VerticalScrollBarWidth
, 0,
744 SystemInformation
.VerticalScrollBarWidth
, ClientRectangle
.Height
);
746 /* the ScrollWindow calls here are needed
747 * because (this explanation sucks):
749 * when we transition from having a scrollbar to
750 * not having one, we won't receive a scrollbar
751 * moved (value changed) event, so we need to
752 * manually scroll the canvas.
754 * if you can fix this without requiring the
755 * ScrollWindow calls, pdb and toshok will each
758 if (hscroll_visible
) {
759 hscrollbar
.LargeChange
= right_edge
;
760 hscrollbar
.SmallChange
= 5;
761 hscrollbar
.Maximum
= canvas
.Width
- 1;
763 if (hscrollbar
!= null && hscrollbar
.VisibleInternal
) {
764 ScrollWindow (- scroll_position
.X
, 0);
766 scroll_position
.X
= 0;
769 if (vscroll_visible
) {
770 vscrollbar
.LargeChange
= bottom_edge
;
771 vscrollbar
.SmallChange
= 5;
772 vscrollbar
.Maximum
= canvas
.Height
- 1;
774 if (vscrollbar
!= null && vscrollbar
.VisibleInternal
) {
775 ScrollWindow (0, - scroll_position
.Y
);
777 scroll_position
.Y
= 0;
780 if (hscroll_visible
&& vscroll_visible
) {
781 hscroll_bounds
.Width
-= SystemInformation
.VerticalScrollBarWidth
;
782 vscroll_bounds
.Height
-= SystemInformation
.HorizontalScrollBarHeight
;
784 sizegrip
.Bounds
= new Rectangle (hscroll_bounds
.Right
,
785 vscroll_bounds
.Bottom
,
786 SystemInformation
.VerticalScrollBarWidth
,
787 SystemInformation
.HorizontalScrollBarHeight
);
792 hscrollbar
.Bounds
= hscroll_bounds
;
793 hscrollbar
.Visible
= hscroll_visible
;
795 vscrollbar
.Bounds
= vscroll_bounds
;
796 vscrollbar
.Visible
= vscroll_visible
;
798 UpdateSizeGripVisible ();
803 internal void UpdateSizeGripVisible ()
805 sizegrip
.CapturedControl
= Parent
;
806 // This is really wierd, the size grip is only showing up
807 // if the bottom right corner of the scrollable control is within
808 // two pixels from the bottom right corner of its parent.
809 bool show_sizegrip
= hscrollbar
.VisibleInternal
&& vscrollbar
.VisibleInternal
;
810 bool enable_sizegrip
= false;
811 if (show_sizegrip
&& Parent
!= null) {
812 Point diff
= new Point (Parent
.ClientRectangle
.Bottom
- Bottom
, Parent
.ClientRectangle
.Right
- Right
);
813 enable_sizegrip
= diff
.X
<= 2 && diff
.X
>= 0 && diff
.Y
<= 2 && diff
.Y
>= 0;
815 sizegrip
.Visible
= show_sizegrip
;
816 sizegrip
.Enabled
= enable_sizegrip
|| sizegrip
.Capture
;
819 private void HandleScrollBar(object sender
, EventArgs e
) {
820 if (sender
== vscrollbar
) {
821 ScrollWindow(0, vscrollbar
.Value
- scroll_position
.Y
);
823 ScrollWindow(hscrollbar
.Value
- scroll_position
.X
, 0);
827 private void CreateScrollbars ()
829 hscrollbar
= new ImplicitHScrollBar ();
830 hscrollbar
.Visible
= false;
831 hscrollbar
.ValueChanged
+= new EventHandler (HandleScrollBar
);
832 hscrollbar
.Height
= SystemInformation
.HorizontalScrollBarHeight
;
833 this.Controls
.AddImplicit (hscrollbar
);
835 vscrollbar
= new ImplicitVScrollBar ();
836 vscrollbar
.Visible
= false;
837 vscrollbar
.ValueChanged
+= new EventHandler (HandleScrollBar
);
838 vscrollbar
.Width
= SystemInformation
.VerticalScrollBarWidth
;
839 this.Controls
.AddImplicit (vscrollbar
);
841 sizegrip
= new SizeGrip (this);
842 sizegrip
.Visible
= false;
843 this.Controls
.AddImplicit (sizegrip
);
846 private void ScrollWindow(int XOffset
, int YOffset
) {
849 if (XOffset
== 0 && YOffset
== 0) {
855 num_of_children
= Controls
.Count
;
857 for (int i
= 0; i
< num_of_children
; i
++) {
858 Controls
[i
].Left
-= XOffset
;
859 Controls
[i
].Top
-= YOffset
;
860 // Is this faster? Controls[i].Location -= new Size(XOffset, YOffset);
863 scroll_position
.X
+= XOffset
;
864 scroll_position
.Y
+= YOffset
;
866 // Should we call XplatUI.ScrollWindow??? If so, we need to position our windows by other means above
867 // Since we're already causing a redraw above
871 #endregion // Internal & Private Methods
874 static object OnScrollEvent
= new object ();
876 protected virtual void OnScroll (ScrollEventArgs se
)
878 EventHandler eh
= (EventHandler
) (Events
[OnScrollEvent
]);
883 protected override void OnPaintBackground (PaintEventArgs e
)
885 base.OnPaintBackground (e
);
888 [EditorBrowsable (EditorBrowsableState
.Advanced
)]
889 protected override void OnRightToLeftChanged (EventArgs e
)
891 base.OnRightToLeftChanged (e
);
894 public event ScrollEventHandler Scroll
{
895 add { Events.AddHandler (OnScrollEvent, value); }
896 remove { Events.RemoveHandler (OnScrollEvent, value); }