Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

.NET ListView: Reacting to Column Resize When User Doubleclicks Header Separator

4.33/5 (3 votes)
1 Sep 2010CPOL2 min read 12.8K  
I just came up with a hack for .NET ListView to react to users doubleclider separator to auto resize the column to fit column contents.

I just came up with a hack for .NET ListView to react to users doubleclicking the header separator to auto resize the column to fit column contents. The reason why I need this is that I'm creating a custom control, that’s a mix of ListView and TreeView and in the first column, I'm drawing the plus sign, as there’s in every TreeView.

However, when user double clicks the header separator of the first column and column is auto resized, that addition of mine is not taken into account. Column is resized to the text width only, leaving some of the text out, as seen in the image below:

Example

So the only way to fix this is to subscribe to the correct event and add to the column width there. Great, isn’t it?. The bad news is that there is no such event in .NET… :( But I had to get around it and I didn’t want to use P/Invoke and call unmanaged code. This is what I came up with:

C#
private int widthChangingCount = 0;
private bool manuallySettingWidth = false;
 
protected override void OnColumnWidthChanging(ColumnWidthChangingEventArgs e)
{
	if (manuallySettingWidth == false && e.ColumnIndex == 0)
		widthChangingCount++;
 
	base.OnColumnWidthChanging(e);
}
 
protected override void OnColumnWidthChanged(ColumnWidthChangedEventArgs e)
{
	// if we only had 1 resizing event raised, 
         // we're sure that the divider was doubleclicked
	if (manuallySettingWidth == false && e.ColumnIndex == 0 && 
		widthChangingCount == 1)
	{
		manuallySettingWidth = true;
		Columns[e.ColumnIndex].Width += 40;
 
		manuallySettingWidth = false;
	}
 
	widthChangingCount = 0;
 
	base.OnColumnWidthChanged(e);
}

So, in the class that derives from ListView, override these two methods. OnColumnWidthChanging is called when user clicks on the separator and drags it to resize column. It gets called a few times before the mouse button is released.

The trick with double clicking the header is: OnColumnWidthChanging gets called only once. I used this as the means to identify resizing in this way. As far as I tested, I couldn't manually resize the header so quick that OnColumnWidthChanging would get called only once. So in OnColumnWidthChanged method, I add the width of my image to the column width. Be careful however, that changing column size from code also calls OnColumnWidthChanging once, that’s why I added the manuallySettingWidth boolean to help here.

Quite ugly, but works so far. :)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)