向 Control 发送 LVM_APPROXIMATEVIEWRECT 消息,您可以返回一个大致的测量值,包括 Header 的高度和所有 Item 的大小。
将 Control 的 ClientSize 设置为此度量,应该允许调整 ListView 的大小,以显示所有项目的完整范围。
您可以指定要包含的项目数量 (wParam) 和首选大小 (lParam),或者将 lParam 和 wParam 都设置为 -1:在这种情况下,所有项目都包括在内并且会自动检测大小。
请注意,高度可能包括水平滚动条高度:在底部可能会看到一个边距。
如果不希望这样做,请从整体高度中删除 SystemInformation.HorizontalScrollBarHeight。
或者,如果 ListView 中的项目数建议,则执行相同的操作以将 Control 的范围限制为特定度量。
► 如 cmets 中所述,如果 ListView 停靠在 Form 上,设置其 ClientSize 没有任何可见效果。
在这种情况下,您还需要调整表单的大小,添加 ListView 的旧大小与其新计算大小之间的差异。
假设 ListView 被命名为listView1:
Size oldSize = listView1.ClientSize;
int hScrollBarHeight = SystemInformation.HorizontalScrollBarHeight
// Both wParam and lParam set to -1: include all Items and full size
int approxSize = NativeMethods.SendMessage(
listView1.Handle, NativeMethods.LVM_APPROXIMATEVIEWRECT, -1, (-1 << 16 | -1));
int approxHeight = approxSize >> 16;
int approxWidth = approxSize & 0xFFFF;
Size newSize = new Size(approxWidth, approxHeight - hScrollBarHeight);
// If needed, resize the Form (here, grow and shrink) to adapt to the new size
// Checking the Dock property state is a possible example, apply whatever logic fits
if (listView1.Dock != DockStyle.None) {
this.Height += newSize.Height - oldSize.Height;
this.Width += newSize.Width - oldSize.Width;
}
listView1.ClientSize = newSize;
internal class NativeMethods
{
internal const int LVM_FIRST = 0x1000;
internal const int LVM_APPROXIMATEVIEWRECT = LVM_FIRST + 0x40;
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, int lParam);
}