Resizing List View Columns in .NET
If you want to make your list view controls resize the columns so their widths will be long enough to show the column text along with any row information in .NET, it's pretty easy, but the way to do it is a little odd. Take a look at the following application:
The screen shot was taken after the Populate button was pressed. As you can see, the last entry is too long given the current width values of the columns.
What I wanted to do was to make the view a bit more intelligent than that. I knew there was a way to do this with straight Win32 programming - check out Randy Birch's article, "Autosizing ListView Columns via API". It shows you everything you need to get this to work in VB6. Of course, I was hoping there would be a far easier way to do it in .NET than to rely on API calls, and there is. The code underneath the Width = -2 button shows you how it works:
Private Sub btnWidthMinusTwo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnWidthMinusTwo.Click
Dim oHeader As ColumnHeader
For Each oHeader In Me.lvwTest.Columns
oHeader.Width = -2
After you run the code, the list view will look like this:
Perfect! The only issue I have with this is that it wasn't obvious to me to change the
Width property to -2. If you look at the SDK, it'll tell you that you can only do this at run-time (try setting that property to -2 in the Designer and you'll see what I mean). OK, but this just feels awkward, like it's a holdover to the Win32 API days. And, sure enough, it is. If you look at Birch's article, you'll see that the constant you need to adjust the column widths is called
LVSCW_AUTOSIZE_USEHEADER - its' value is (you guessed it) -2. By the way, the reason I have a Width = -1 button was just a test of mine - -1 is another valid value according to the SDK (it's the value for
LVSCW_AUTOSIZE). After clicking that, the screen will look like this:
This wasn't quite what I had in mind. This will only resize according to the text in the columns, so if there's nothing in the column (as is the case with my Middle Name column) it'll get scrunched.
My original hope was that there would be something along the lines of a property called
ColumnResizing that would take an enumeration called
ColumnResizingBehavior with the following values:
AutoSizeUseHeader. That way, when you'd set
Width property would be able to tell you what the new column width was. The way it works now, after you set
Width to -2, you have no idea what the true width is because you'll get a -2 back when you retrieve
It's a small nit, and it's nice that it only takes a couple of lines of .NET code to pull it off. But it would've been nice to make this feature a bit more .NET/OO-oriented. I mean, setting a
Width property to a negative value to make the column auto-size is not semantically correct in my book. Using a property is a better approach.