Tuesday, October 19, 2010

ScrollableControl and Panel: Mouse Scroll and Draw (.NET C#)

The ScrollableControl class is great if you are creating a control that will need to display the scroll bars vertically and horizontally. The Panel control does the same with the controls added to it. Unfortunately, by default, when you drag the scroll bar with the mouse the rest of the control does not draw until you let up on the mouse button. In every application I have created I have never wanted this behavior. I finally took some time to investigate and found 1 magical line of code. Followed up by 5 further magical lines of code.

SetScrollState(ScrollableControl.ScrollStateFullDrag, true);
public static void SetupScrollState(ScrollableControl scrollableControl)
 Type scrollableControlType = typeof(ScrollableControl);
 MethodInfo setScrollStateMethod = scrollableControlType.GetMethod("SetScrollState", BindingFlags.NonPublic | BindingFlags.Instance);
 setScrollStateMethod.Invoke(scrollableControl, new object[] { ScrollableControl.ScrollStateFullDrag, true });

SetScrollState on MSDN
ScrollStateFullDrag on MSDN

By enabling the ScrollStateFullDrag your control will hit the OnPaint event each time the scroll value changes. Though beware... there is one minor issue I ran into. The state of the flag appears to be reset each time the size of the scrollable control changes. In my case each time I changed the AutoScrollMinSize I just called SetScrollState again.

The second block of code (the SetupScrollState method) is a bit more back door approach to setting up the ScrollStateFullDrag on your ScrollableControls. I found a good post by someone by the nickname dpuza (forum link) indicating an approach by which to call the protected SetScrollState method in your ScrollableControl. It works well, though you may feel a bit wrong making the reflection call... This is one approach to setup your existing Panel control to draw and scroll without creating a new PanelEx type of class.

1 comment: