C# 如何在详细信息模式下隐藏.NET ListView控件中的垂直滚动条

C# 如何在详细信息模式下隐藏.NET ListView控件中的垂直滚动条,c#,winforms,listview,C#,Winforms,Listview,我有一个在细节模式下的ListView控件,只有一列。它位于一个只能与键盘一起使用的表单上,主要是上下箭头用于滚动和输入选择。所以我不需要滚动条,我只希望它们不显示,看起来更干净。但是,当我将ListView.Scrollable属性设置为false时,我仍然可以上下移动所选项目,但只要它移动到当前未在视图中的项目,列表就不会移动以显示该项目。我曾尝试使用EnsureRevible以编程方式滚动列表,但在这种模式下它什么也不做 有没有办法在不显示滚动条的情况下手动上下移动列表以进行滚动?调用AP

我有一个在细节模式下的ListView控件,只有一列。它位于一个只能与键盘一起使用的表单上,主要是上下箭头用于滚动和输入选择。所以我不需要滚动条,我只希望它们不显示,看起来更干净。但是,当我将ListView.Scrollable属性设置为false时,我仍然可以上下移动所选项目,但只要它移动到当前未在视图中的项目,列表就不会移动以显示该项目。我曾尝试使用EnsureRevible以编程方式滚动列表,但在这种模式下它什么也不做


有没有办法在不显示滚动条的情况下手动上下移动列表以进行滚动?

调用API方法。

如果
ShowScrollBar
不起作用,我不知道该怎么做


您可以将ListView放在一个面板中,并使ListView比面板更宽,这样滚动条就被切断了(请检查
SystemInformation.VerticalScrollBarWidth
),但这是一个非常丑陋的黑客行为。

既然ShowScrollBar不起作用,也许这有助于:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

private const int WM_VSCROLL = 0x115;
private const int SB_LINEDOWN = 1;

public Form1()
{
    InitializeComponent();
    for (int i = 0; i < 100; i++)
        listView1.Items.Add("foo" + i);
    listView1.Scrollable = false;
}

private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
    SendMessage(listView1.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
}
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
静态外部IntPtr SendMessage(IntPtr hWnd、UInt32 Msg、int wParam、int lParam);
私有常量int WM_VSCROLL=0x115;
私有const int SB_LINEDOWN=1;
公共表格1()
{
初始化组件();
对于(int i=0;i<100;i++)
列表视图1.Items.Add(“foo”+i);
listView1.Scrollable=false;
}
私有无效列表视图1\u SelectedIndexChanged(对象发送方,事件参数e)
{
SendMessage(listView1.Handle,WM_VSCROLL,SB_LINEDOWN,0);
}

这不容易,但可以做到。如果您试图通过ShowScrollBar隐藏滚动条,ListView将再次将其放回原处。所以你必须做些更狡猾的事

您必须截获WM_NCCALCSIZE消息,并在其中关闭垂直滚动样式。每当listview试图再次打开它时,您将在此处理程序中再次关闭它

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);
}

这将为您提供一个没有滚动条的列表视图,当您使用箭头键更改选择时,滚动条仍会滚动。

我做了一些更简单的事情。我将scrollable设置为true,并使用了在codeproject上找到的自定义滑块(colorSlider),将滑块拖到vscroller将出现的位置,然后使用EnsureRevible函数。

您可以使用ListView.scrollable属性。将其设置为false,滚动条将不会出现

使用[DllImport(“user32.dll”)]静态外部bool显示滚动条(IntPtr hWnd、intwbar、bool bShow);带有:ShowScrollBar(lstMain.Handle,3,false);但它不起作用…尝试在
布局
调整大小
事件中调用它。另外,请参见此处:此处:我尝试了相同的代码用于水平滚动(我将0x00200000替换为0x00100000),滚动条隐藏,但无法使用箭头键滚动。有什么想法吗?这段代码对常规行运行良好,但标题看起来是错误的,它似乎没有重新绘制覆盖滚动条的区域。顺便说一句,我使用的是ObjectListView,它是Listview的一个子类。