开发者

Internal Size of a ListView without scrollbars

What I want to get is size of a ListView control but not size that is displayed but rather size of it when it would be fully expanded (i.e. without any scrollbars). Is this possible? How开发者_StackOverflow can I calculate this?

EDIT: What I'm trying to accomplish is to resize that control so that it won't need to be scrolled (panel containing this control and some more is scrollable)


This is fairly difficult to accomplish with a ListView control, especially if you have it set to "Details" view. There's no easy way to determine the size of the column headers. If you're targeting Windows Vista or later, the simple answer is to set the LVS_EX_AUTOSIZECOLUMNS extended style, which will automatically resize the columns displayed in the ListView to best fit the data on the screen.

Another option to consider is sending the LVM_APPROXIMATEVIEWRECT message, which is documented to return the approximate height and width required for a ListView control to display the specified number of items. I've never actually used this myself, but it looks promising. I'm not sure how exactly it works for "Details" view, but it should at least work perfectly fine for the other icon views.

You'll need to P/Invoke to use this in .NET. These definitions will help get you started:

private const int LVM_FIRST = 0x1000;
private const int LVM_APPROXIMATEVIEWRECT = LVM_FIRST + 64;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
  • Specify the handle to the ListView control (myListView.Handle) as the hWnd parameter.
  • The msg parameter is, of course, LVM_APPROXIMATEVIEWRECT.
  • The docs say that the wParam can be set to -1 to use the total number of items in the control.
  • The low-order word of the lParam is the proposed x-dimension of the control, in pixels. The high-order word is the proposed y-dimension. Either can be set to -1 to use the current value. You'll need to do some bit-twiddling since you don't have the handy macros.
  • And the return value contains the width in the low-order word and the height in the high-order word. Again, you'll need to extract those values with some bit-twiddling.

Example bit-twiddling functions:

public static int LoWord(IntPtr dw)
{
   return (dw.ToInt32() & 0xffff);
}

public static int HiWord(IntPtr dw)
{
   return ((dw.ToInt32() >> 16) & 0xffff);
}

private static IntPtr MakeLParam(int loWord, int hiWord)
{
    return (IntPtr)((hiWord << 16) | (loWord & 0xffff));
}


If you are talking Details View:

If you are talking the Height of the control, I'd suggest not doing it. See this discussion for some rationale.

If you are talking Width of the control then you need to add up the width of each column. There's a border in there somewhere of 2 pixels on each side - which I'm sure you can determine where it's coming from.

int width = 2 * 2;
foreach (ColumnHeader column in this.listView1.Columns)
{
    width += column.Width;
}

this.listView1.Width = width;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜