10

is there a way I can stop the horizontal scroll bar from ever showing up in a listview? I want the vertical scroll bar to show when needed but I want the horizontal scroll bar to never show up.

I would imagine it would have something to do with WndProc?

Thanks

Ozzy
  • 9,867
  • 26
  • 90
  • 137

4 Answers4

9

There is a much simpler way to eliminate the lower scroll bar and have the vertical showing. It consists of making sure the header and if no header the rows are the width of the listview.Width - 4 and if the vertical scroll bar is show then listview.Width - Scrollbar.Width - 4;

the following code demostrates how to:

lv.Columns[0].Width = lv.Width - 4 - SystemInformation.VerticalScrollBarWidth;
T.Todua
  • 49,021
  • 18
  • 212
  • 206
Dean McCoy
  • 113
  • 1
  • 1
  • That is indeed a much cleaner approach than the selected answer and actually the root cause of the problem. The column(s) of the ListView need to be smaller. Thanks for that hint, it worked for me. – Tobias Sep 16 '15 at 14:35
  • 2
    I don't think this will work if you use check box rows. Also I don't think that fixed values are good as other windows designs will maybe use different sizes. And last but not least this is not a cleaner approach. If you don't want a scroll bar you should hide/disable it and not adjust something else so it won't be shown. I don't like the p/Invoke solutions but it is still a better approach than the column width adjustment. – Robert S. Oct 19 '16 at 14:03
  • This worked for me as well, but in the final code snippet, shouldn't `Width` be changed to something like `width` or `widthValue`, to clarify that the answer isn't referring to `this.Width` inside of a UI component/control class? I almost edited the letter's case myself, but feel like the OP should verify that this is the intent. – Panzercrisis Mar 03 '17 at 21:16
5

The currently accepted answer is unsafe, as it unbalances the stack. you should use the following code instead for the DllImport:

[System.Runtime.InteropServices.DllImport("user32", CallingConvention=System.Runtime.InteropServices.CallingConvention.Winapi)]
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]

private static extern bool ShowScrollBar(IntPtr hwnd, int wBar, [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)] bool bShow);

Andreas Reiff covers this in his comment above after looking again, so I guess here it is all nicely formatted.


In order to use it:

# Use one of these valued for hwnd
long SB_HORZ = 0;
long SB_VERT = 1;
long SB_BOTH = 3;

# Use the actual name of the ListView control in your code here
# Hides the specified ListView scroll bar
ShowScrollBar(listView1.Handle.ToInt64(), SB_BOTH, 0);

To instead force it to show instead of hide, simply change bShow from 0 to 1, since 0 equates to false and 1 equates to true.

Bender the Greatest
  • 17,062
  • 18
  • 82
  • 145
  • Any idea how to use this but still allow scrolling? I'd like to use for vertical scroll. Thanks – Lee Dec 17 '20 at 22:11
  • I believe hiding the scrollbar though has the side effect of disabling scrolling. I won't say it's impossible though as I've been out of writing WinForms for some time, but rather that I'm unaware of any method to hide the bar while still allowing scrolling. – Bender the Greatest Oct 15 '21 at 16:03
4

You could try something like this, I used in a project once and it worked:

[DllImport ("user32")]
private static extern long ShowScrollBar (long hwnd , long wBar, long bShow);
long SB_HORZ = 0;
long SB_VERT = 1;
long SB_BOTH = 3;

private void HideHorizontalScrollBar ()
{
    ShowScrollBar(listView1.Handle.ToInt64(), SB_HORZ, 0);
}

Hope it helps.

bennyyboi
  • 229
  • 3
  • 9
  • 1
    hi can you pls explain this, or can you tell me how i can read up on all these direct windows api calls – swordfish May 20 '11 at 03:16
  • 1
    Instead of `long hwnd` you could use `IntPtr hwnd` as the first parameter to the P/Invoke method. – Uwe Keim Jun 27 '12 at 09:56
  • Second that, for P/Invokes, alsways look at pinvoke. :) http://www.pinvoke.net/default.aspx/user32/ShowScrollBar.html gives signature [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ShowScrollBar(IntPtr hWnd, int wBar, [MarshalAs(UnmanagedType.Bool)] bool bShow); Only problem (I think) is IntPtr which Uwe already has mentioned. – Andreas Reiff Jul 04 '12 at 13:25
  • 2
    As already mentioned the P/Invoke definition of this answer is plain *wrong* - do not use it! `long` is 8 bytes while e.g. for a 32 bit process all arguments need to be 4 byte. It's just plain luck it works because 2nd and 3rd argument are zero. – Zarat May 06 '13 at 08:47
3

The best solution is the accepted answer that was given here: How to hide the vertical scroll bar in a .NET ListView Control in Details mode

It works perfectly and you don't need some tricks like column width adjustments. Moreover you disable the scrollbar right when you create the control.

The drawback is that you have to create your own list view class which derives from System.Windows.Forms.ListView to override WndProc. But this is the way to go.

To disable the horizontal scroll bar, remember to use WS_HSCROLL instead of WS_VSCROLL (which was used in the linked answer). The value for WS_HSCROLL is 0x00100000.

Community
  • 1
  • 1
Robert S.
  • 1,794
  • 13
  • 22