How to hide the vertical scroll bar in a .NET ListView Control in Details mode

前端 未结 6 1549
终归单人心
终归单人心 2020-12-01 17:11

I\'ve got a ListView control in Details mode with a single column. It\'s on a form that is meant to only be used with the keyboard, mostly with the up/down arrows for scrol

6条回答
  •  自闭症患者
    2020-12-01 17:54

    It's not easy but it can be done. If you try to hide the scroll bar through ShowScrollBar, the ListView will simply put it back again. So you have to do something more devious.

    You will have to intercept the WM_NCCALCSIZE message, and in there, turn off the vertical scroll style. Whenever the listview tries to turn it on again, you will turn it off again in this handler.

    public class ListViewWithoutScrollBar : ListView
    {
        protected override void WndProc(ref Message m) {
            switch (m.Msg) {
                case 0x83: // WM_NCCALCSIZE
                    int style = (int)GetWindowLong(this.Handle, GWL_STYLE);
                    if ((style & WS_VSCROLL) == WS_VSCROLL)
                        SetWindowLong(this.Handle, GWL_STYLE, style & ~WS_VSCROLL);
                    base.WndProc(ref m);
                    break;
                default:
                    base.WndProc(ref m);
                    break;
            }
        }
        const int GWL_STYLE = -16;
        const int WS_VSCROLL = 0x00200000;
    
        public static int GetWindowLong(IntPtr hWnd, int nIndex) {
            if (IntPtr.Size == 4)
                return (int)GetWindowLong32(hWnd, nIndex);
            else
                return (int)(long)GetWindowLongPtr64(hWnd, nIndex);
        }
    
        public static int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong) {
            if (IntPtr.Size == 4)
                return (int)SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
            else
                return (int)(long)SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
        }
    
        [DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
        public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
    
        [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)]
        public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
    
        [DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
        public static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, int dwNewLong);
    
        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
        public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong);
    }
    

    This will give you a ListView without scroll bars that still scrolls when you use the arrow keys to change selection.

提交回复
热议问题