Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force vertical scrollbar always be visible from AutoScroll in WinForms?

Using VS2010 and .NET 4.0 with C# and WinForms:

I always want a Vertical Scrollbar to show for my panel as a disabled scrollbar (when it's not needed, and a enabled one when it can be used.

So it's like a hybrid AutoScroll. I've tried using VScrollBars but I can't figure out where to place them to make this work.

Essentially I've got a user control that acts as a "Document" of controls, its size changes so when using auto-scroll it works perfectly. The scrollbar appears when the usercontrol doesn't fit and the user can move it updown.

It's like a web browser essentially. However, redrawing controls takes a long time (it's forms with many fields and buttons etc within groups in a grid within a panel :P

So anyhow, when autoscroll enables the vertical scrollbar, it takes a while to redraw the window. I'd like to ALWAYS show the vertical scrollbar as indicated above (with the enable/disable functionality).

If anyone has some help, i've read many posts on the subject of autoscroll, but noone has asked what I'm asking and I can't come up with a solution.

like image 921
user1104203 Avatar asked Dec 31 '11 21:12

user1104203


3 Answers

What worked for me was overriding the CreateParams call and enabling the WS_VSCROLL style.

public class VerticalFlowPanel : FlowLayoutPanel
{
    protected override CreateParams CreateParams
    {
        get
        {
            var cp = base.CreateParams;
            cp.Style |= 0x00200000; // WS_VSCROLL
            return cp;
        }
    }
}

The AutoScroll logic will now adjust the scrolling bounds without ever hiding the scrollbar.

like image 89
BradJ Avatar answered Nov 02 '22 12:11

BradJ


C# Version of competent_Tech's answer

using System.Runtime.InteropServices; 

public class MyUserControl : UserControl
{
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool ShowScrollBar(IntPtr hWnd, int wBar, bool bShow);

    private enum ScrollBarDirection
    {
        SB_HORZ = 0,
        SB_VERT = 1,
        SB_CTL = 2,
        SB_BOTH = 3
    }

    public MyUserControl()
    {
        InitializeComponent();
        ShowScrollBar(this.Handle, (int) ScrollBarDirection.SB_VERT, true);
    }
}
like image 34
fiat Avatar answered Nov 02 '22 12:11

fiat


You can use the auto-scroll functionality of the panel, you just need to send it a windows message to show the vertical scrollbar:

<DllImport("user32.dll")> _
Public Shared Function ShowScrollBar(ByVal hWnd As System.IntPtr, ByVal wBar As Integer, ByVal bShow As Boolean) As Boolean
End Function

Private Const SB_VERT As Integer = 1


Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ShowScrollBar(Panel1.Handle, SB_VERT, True)
End Sub

The scrollbar will be displayed and appear as though it can be scrolled, but it won't do anything until it is actually ready to scroll. If you disable it, it won't be automatically re-enabled, so this is probably the best approach.

Also, to improve the performance while resizing, you can call SuspendLayout on the panel before updating and ResumeLayout when done.

like image 4
competent_tech Avatar answered Nov 02 '22 14:11

competent_tech