有没有办法在ListView中防止水平滚动条的出现?我希望当需要时显示垂直滚动条,但是永远不要显示水平滚动条。
我想这可能与WndProc有关吗?
谢谢
有没有办法在ListView中防止水平滚动条的出现?我希望当需要时显示垂直滚动条,但是永远不要显示水平滚动条。
我想这可能与WndProc有关吗?
谢谢
有一种更简单的方法可以消除下方滚动条并显示垂直滚动条。它包括确保标题和如果没有标题,则行的宽度为listview.Width - 4
,如果显示垂直滚动条,则为listview.Width - Scrollbar.Width - 4;
以下代码演示了如何实现:
lv.Columns[0].Width = lv.Width - 4 - SystemInformation.VerticalScrollBarWidth;
目前被接受的答案是不安全的,因为它会导致堆栈不平衡。您应该使用以下代码来进行 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);
为了使用它:
# 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);
bShow
从 0
更改为 1
,因为 0
相当于 false
,而 1
相当于 true
。System.Windows.Forms.ListView
以覆盖WndProc
。但这是正确的方法。WS_HSCROLL
而不是WS_VSCROLL
(链接答案中使用了WS_VSCROLL
)。WS_HSCROLL
的值为0x00100000
。
[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);
}
long hwnd
改为IntPtr hwnd
。 - Uwe Keimlong
是8字节,而例如对于32位进程,所有参数都需要是4字节。它之所以能够工作,仅仅是因为第二个和第三个参数恰好为零。 - Zaratusing System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace LancourWestbrook.Controls
{
public partial class TPListView : ListView
{
[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);
const int GWL_STYLE = -16;
const int WS_VSCROLL = 0x00200000;
const int WS_HSCROLL = 0x00100000;
const int WM_MOUSEWHEEL = 0x20a;
const int WM_NCCALCSIZE = 0x83;
public TPListView()
{
InitializeComponent();
}
public TPListView(IContainer container)
{
container.Add(this);
InitializeComponent();
}
private int? LastItemIndexInView
{
get
{
if (this.Items == null || this.Items.Count <= 0)
{
return null;
}
List<int> items = new List<int>();
int topIndex = this.TopItem.Index;
int currentIndex = topIndex;
items.Add(topIndex);
while (1 == 1)
{
currentIndex++;
if (this.Items.Count - 1 < currentIndex)
{
break;
}
if (this.Items[currentIndex].Bounds.IntersectsWith(this.ClientRectangle))
{
items.Add(currentIndex);
}
else
{
break;
}
}
return currentIndex;
}
}
public bool ScrollOverride { get; set; }
protected override void WndProc(ref Message m)
{
if (ScrollOverride == false)
{
base.WndProc(ref m);
return;
}
switch (m.Msg)
{
case WM_MOUSEWHEEL:
if (this.Items == null || this.Items.Count <= 0)
{
break;
}
var zDelta = (short)HIWORD(m.WParam);
if (zDelta < 0)
{
//Scroll Downwards
int? lastItemInView = LastItemIndexInView;
if (lastItemInView.HasValue && this.Items.Count > lastItemInView.Value + 1)
{
this.Items[lastItemInView.Value + 1].EnsureVisible();
}
else if (this.Items.Count > 0)
{
this.Items[this.Items.Count - 1].EnsureVisible();
}
}
else if (zDelta > 0)
{
//Scroll Upwards
int topItemInView = this.TopItem.Index;
if (topItemInView > 0)
{
this.Items[topItemInView - 1].EnsureVisible();
}
}
break;
case WM_NCCALCSIZE:
int style = (int)GetWindowLong(this.Handle, GWL_STYLE);
if ((style & WS_VSCROLL) == WS_VSCROLL)
SetWindowLong(this.Handle, GWL_STYLE, style & ~WS_VSCROLL);
if ((style & WS_HSCROLL) == WS_HSCROLL)
SetWindowLong(this.Handle, GWL_STYLE, style & ~WS_HSCROLL);
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
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);
}
internal static ushort HIWORD(IntPtr dwValue)
{
return (ushort)((((long)dwValue) >> 0x10) & 0xffff);
}
}
}
Width
不应该改为类似于width
或widthValue
之类的内容吗?以澄清答案并非指UI组件/控件类内部的this.Width
。我差点自己编辑了字母大小写,但觉得应该由OP验证这是否是意图。 - Panzercrisis