Ehm, umm, this means some lines should be two-lined in size. My boss think this is more simple solution, than limit displayed text to fit width and don't like horizontal scroll bar >_<
Asked
Active
Viewed 2.2k times
4 Answers
39
lst.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
lst.MeasureItem += lst_MeasureItem;
lst.DrawItem += lst_DrawItem;
private void lst_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemHeight = (int)e.Graphics.MeasureString(lst.Items[e.Index].ToString(), lst.Font, lst.Width).Height;
}
private void lst_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
e.Graphics.DrawString(lst.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds);
}

Kosmo零
- 4,001
- 9
- 45
- 88
-
Love it. One minor thing though. When I databind a custom class, the DisplayMember gets wiped and I can't seem to reset it. Any tips? – Bill Sambrone Mar 25 '14 at 23:58
-
@BillSambrone - Sorry, but I don't use databind and never meet same problem and don't know how to solve. – Kosmo零 Mar 27 '14 at 20:03
-
@AycanYaşıt : totaly agree – Sebastien H. Aug 27 '14 at 10:44
-
@Kosmos Seems that the `ListBox` caches the items height, what is good. The problem is that if the `ListBox` is resized it don't recalculates the height! I'm trying someway to clean the cache of items height without removing and adding then, in the `resize`, but I don't find any method for that. At least documented. – Diego C Nascimento Feb 12 '15 at 15:13
-
@DiegoCNascimento - I used `ListBox.Refresh` method in `resize` handler for that. – Kosmo零 Feb 12 '15 at 19:41
-
@Kosmos `Refresh` does not work, it will just add all the area of the `ListBox` to next `Paint` event, but does not calculate the new items height. – Diego C Nascimento Feb 13 '15 at 00:39
-
@DiegoCNascimento - I don't know why, but for me it worked fine. I used Form's resize event and called list box's Refresh method. I don't know why you telling it's not working. Refresh causes control to redraw and when it redraws it should run the calculation code again. – Kosmo零 Feb 13 '15 at 16:32
-
@Kosmos what version of .Net are you using (even trough the `ListBox` is a native windows control)? It don't raise the `MeasureItem` event, you can search for the same question in other places. Anyway I found [a way to change item height](http://stackoverflow.com/questions/28490543/windows-forms-listbox-with-ownerdrawvariable-bug) – Diego C Nascimento Feb 15 '15 at 15:43
-
Also take a look at that **Unfortunately, the MeasureItem event only happens when the handle gets created** in [this answer](http://stackoverflow.com/questions/7072539/expanding-selected-item-height-in-listbox/7072554). – Diego C Nascimento Feb 15 '15 at 15:50
-
@DiegoCNascimento - Meh, I tested it and finally understand what you meant. I though that text stays the same after resizing (no updates), but the text changes according to space available, while item height no. Well..., currently I don't know what to do. – Kosmo零 Feb 15 '15 at 21:54
-
@Kosmos Yes, that's it. Putting it, the item height is dependent on the item width, being the item width dependent on the control client area width. I come [with a solution](http://stackoverflow.com/questions/28490543/windows-forms-listbox-with-ownerdrawvariable-bug). The `ListBox` that is a native windows control, has way to set item height, so you can call it with "Windows API". Also, I make a call to the measure item, for each item and called the "Windows API", so that it worked. There's only a glitch when the scroll bar gets show or hidden. Thanks! – Diego C Nascimento Feb 17 '15 at 17:32
-
@BillSambrone If you use a custom class, you need to replace "lst.Items[e.Index].ToString()" to "((CustomClass)lst.Items[e.Index]).YourMethodShowTheClass". – dlopezgonzalez Jul 31 '15 at 10:00
-
Worked like a charm. – Zhong Ri Mar 12 '19 at 08:39
2
private void lst_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemHeight = (int)e.Graphics.MeasureString(lst.Items[e.Index].ToString(), lst.Font, lst.Width).Height;
}
private void lst_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
e.Graphics.DrawString(lst.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds);
}
To get the right display member to show up when data binding, replace
lst.Items[e.Index].ToString()
with a casted version of the property. So if your binding source is class object Car it would look like
((Car)lst.Items[e.Index]).YourDisplayProperty
Then the above functions can appropriately measure the string and draw it. :)

Rich Guernsey
- 66
- 4
0
Check out this answer. It overrides the template of the listbox with a textblock which wraps the text. Hope it's useful. To solve your problem I think you shold add : ScrollViewer.HorizontalScrollBarVisibility="Disabled" . Found it here

Community
- 1
- 1

Andrei Neculai
- 472
- 2
- 5
- 21
0
To make binding correct, be sure to add check "lst.Items.Count > 0" to lst_MeasureItem function. Here is my example:
if (lst.Items.Count > 0)
{
e.ItemHeight = (int)e.Graphics.MeasureString(lst.Items[e.Index].ToString(), lst.Font, lst.Width).Height;
}
Everything else seems to work nicely after that.