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.
 
    