views:

470

answers:

4

Is there a way to determine the displayed height of a Windows Forms ListBox? In an application I am developing, I have a form with a ListBox docked in it. I need to automatically resize the form to remove the any extra space at the bottom which the ListBox does not use due to ListBox.IntegralHeight being set to true. Currently I am sizing the Form using Form.Height divided by ListBox.ItemHeight and then multiplying that value by ListBox.ItemHeight to round off the extra unnecessary height.


this.Height = (this.Height / this.listBox.ItemHeight) * this.listBox.ItemHeight; 

This works great in Vista, but when I take my application to XP, something goes wrong and there still is extra space showing at the bottom of the form.

I can't use ListBox.PreferredHeight because that only gives me the amount of space the ListBox would take if all items were displayed.

A: 

(This should really be a comment but I can't format the code in that)

When you debug on Visa and XP do you get the same values for

this.Height
this.listBox.ItemHeight

before and after your calculation?

ChrisF
A: 

Depending on your app, it may be nice to place your listbox in an appropriate container for layout purposes. Just a suggestion, not really an answer to your Q.

Of course you might consider reflecting thru the above-mentioned containers code to see how they get at the size of contained controls.

GregC
+1  A: 

My problem has been solved.

I found that ListBox.Height returns the displayed height of the ListBox, even if it is docked. That answers my question, but is not the solution to my problem.

Further debugging revealed why the form appeared to size correctly on Vista and incorrectly on XP. The ItemHeight of my owner-drawn ListBox is 16px (because I am drawing 16x16 images for each item), and the ListBox is in a single bordered form with no titlebar. It just so happens that the height of the borders on Vista add up to 16px (the height of an item) while the height of the borders on XP add up 8px. My height calculation was correct, but the problem is that I was setting Form.Height (the whole height of the form, including borders) instead of Form.ClientSize (just the internal area without borders). Thus, on Vista I was losing an item, and on XP the extra space below the list box was the 8 leftover pixels the borders did not take. The code I originally posted with the question has now become:


this.ClientSize = new Size(
    this.ClientSize.Width, 
    (this.ClientSize.Height / this.listBox.ItemHeight) * this.listBox.ItemHeight);

This rounds the client area height to the nearest item and is good for constrained resizing of the form.

If I only wanted to shrink the form to fit the ListBox, the code could be simplified to:


this.ClientSize = new Size(this.ClientSize.Width, this.listBox.Height);

Zach Johnson
+1  A: 

I think that

System.Windows.Forms.SystemInformation.Border3DSize.Height

really helps you in this situation since it tells you the border height

ionut