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 thehWnd
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;
精彩评论