.NET ListView: reacting to column resize when user doubleclicks header separator

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:

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 few times before the mouse button is released.

The trick with double clicking the header is: OnColumnWidthChanging gets called only one time. 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 one. 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 one time, that’s why I added the manuallySettingWidth boolean to help here.

Quite ugly, but works so far 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s