Fog Creek Software
Discussion Board

Welcome! and rules

Joel on Software

Correctly sizing listview columns

I want to display a listview and I want to have it adjust the columns so that the column width is the larger of:

* The width required to display the column heading
* The width required to display the largest value entry in the column

In other words the column is sized such that you can display all data in the column but if the data is less than the width of the column title then I need it set to the width of the column title so it's readable.

You get three options in .NET:
1. Set a column header with to "-2". This will size it to the column header width.
2. Set a column header width to "-1". This will size it to the maximum amounf of data in the column.
3. Set a column header width to an absolute number.

My way to solve my problem is to:
1. Load the titles into the column headers
2. Set the column header widths to "-2".
3. Read the column header widths and save
4. Load the data into the listview
5. Set the column header widths to "-1".
6. If the column header width now is less than the save column header width then set it to the saved value.

Now the problem is that *sometimes* this works, and sometimes it doesn't!

Sometimes when you set the column header width to "-2" then you can look at the width and it will be set to the real value that it adjusted the column width to, to make it display the header.

Other times when you reread the width it still says "-2".

Anyone know why this is happening?

Anyone know how I can fix it?

Or is there an alternative, better, way of doing this?

Monday, March 8, 2004

I just fixed what may be a similar problem: I'm working with a .NET graph control. When I set this control's Bounds property to change its size, and then call a method that returns the dimensions of one of the internal components within the graph, then the dimension that I get isn't the new dimension updated to reflect the new Bounds that I just set.

To work around this I hook the control's Resize event: the Resize method is called after the control has had an opportunity to recalculate its internal layout.

Unfortunately the Resize event seems to be implemented by Control but not by Component: so I don't know what event you can hook to detect when a listview column has been resized.

Christopher Wells
Tuesday, March 9, 2004

The auto-sizing of ListView columns is rather flaky. I always set precalculated column widths based on the expected string widths.

If you can't do that you should probably recalculate the max width whenever you add a new string, using the Graphics.MeasureString method on the hosting control. That's the one string size measuring method in the .NET Framework that seems reliable.

Chris Nahr
Tuesday, March 9, 2004

*  Recent Topics

*  Fog Creek Home