Click here to Skip to main content
Licence 
First Posted 15 Jul 2002
Views 174,713
Bookmarked 37 times

An auto-resize C# ListBox

By | 16 Jul 2002 | Article
A custom ListBox that can resize its items automatically
Before resize After resize After another resize

What's the problem?

I had to write a little tool that validates an input file according to a file format specification. To add some visual candy to the application, I wanted to include a little status window where all relevant parsing messages (errors, warnings and so on) with some descriptive text are shown.

So the first try was to inherit from the standard ListBox class and implement custom drawing code with a little icon, a headline and the message text. To support varying text sizes I subscribed to the MeasureItem event and calculated the item heights individually for each item. This worked fine until I resized my control the first time: No more MeasureItem events!

A quick look into the documentation revealed the sentence: "Occurs when an owner-drawn ListBox is created". As I added my parsing messages to the listbox on the fly, a continuous re-creation of the control was not an option (besides being inefficient). So this was a dead end.

The solution

After playing around with some possible workarounds without success, I came to the conclusion that this would require a more fundamental approach: I had to write an own listbox that would behave like I had expected it from the standard listbox right from the beginning. The task turned out to be easier that I first expected.

The solution consists basically of two classes: ResizableListBox and MessageListBox. The former is the replacement for the standard ListBox class. It tries to mimic the real ListBox as closely as possible regarding events, properties and methods. Although I have to admit that it's not 100% complete (data binding is missing) but it should do the trick in most cases. It does not provide any additional benefit over the original listbox when used alone. The only difference is, that it fires the MeasureItem event every time the control is redrawn. The latter implements the actual custom listbox with the fancy drawing.

How to use it

First add the ResizableListBox to your project. Then create a derived class and subscribe to the MeasureItem event:

public class MessageListBox : ResizableListBox 
{
    public MessageListBox()
    {    
        InitializeComponent();                    
        this.MeasureItem += new MeasureItemEventHandler(
	    this.MeasureItemHandler);
        
        //more ctor code here
        ...
    }
        
    ...
}

Add a event handler and set the MeasureItemEventArgs.ItemHeight property:

private void MeasureItemHandler(
    object sender, MeasureItemEventArgs e)
{

    int MainTextHeight;            
    ParseMessageEventArgs item;
    item =  (ParseMessageEventArgs) Items[e.Index];
    int LinesFilled, CharsFitted;
            
    // as we do not use the same algorithm to calculate 
    // the size of the text (for performance reasons)
    // we need to add some safety margin ( the 0.9 factor ) 
    // to ensure that always all text is displayed
    int width = (int)((this.Width - m_MainTextOffset) * 0.9);
    int height = 200;
    Size sz = new Size(width , height);    

    e.Graphics.MeasureString(item.MessageText, this.Font, sz,
        StringFormat.GenericDefault, out CharsFitted, 
        out LinesFilled);
            
    MainTextHeight = LinesFilled * this.Font.Height;

    e.ItemHeight = IconList.ImageSize.Height + MainTextHeight + 4;
}

To implement your own drawing code also makes sense:

protected override void OnDrawItem( DrawItemEventArgs e)
{
    //custom drawing goes here
    ...
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Christian Tratz

Web Developer

Germany Germany

Member

If you are not living on the edge you are wasting space Wink | ;)

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generaladding to the list next line Pinmemberjinfrics19:22 28 Jun '09  
GeneralTriggering ListBox.Measureitem PinmemberThe_Mega_ZZTer10:18 22 Aug '05  
GeneralRe: Triggering ListBox.Measureitem Pinmembernicorac22:42 5 Nov '08  
GeneralMouse Wheel problem Pinmemberadi88122:02 6 Aug '04  
GeneralAlso, some few advices... Pinmemberadi88122:26 6 Aug '04  
GeneralRe: Also, some few advices... PinmemberChristian Tratz23:27 6 Aug '04  
GeneralRe: Also, some few advices... PinmemberLelieveld1:32 25 Aug '04  
GeneralRe: Mouse Wheel problem Pinmemberlinlinzongzong24:29 17 Apr '05  
GeneralSome adjustments PinmemberLelieveld23:08 16 Jun '04  
GeneralEasier way to do this PinmemberJohan Danforth22:04 13 Jan '04  
GeneralThis code Even not Compiling in VS 2003 PinmemberSYSDBA4:03 9 Jan '04  
GeneralRe: This code Even not Compiling in VS 2003 PinmemberChristian Tratz6:21 11 Jan '04  
GeneralRe: This code Even not Compiling in VS 2003 PinmemberLelieveld22:57 16 Jun '04  
GeneralFixed a bug computing AutoScrollMinSize PinmemberMike Staley20:05 6 Oct '02  
GeneralRe: Fixed a bug computing AutoScrollMinSize Pinmemberjunkmegently12:56 20 Nov '02  
GeneralRe: Fixed a bug computing AutoScrollMinSize PinmemberMatt Whitfield12:00 7 Sep '08  
Questionsome unneeded work? PinmemberAndy Smith7:50 16 Jul '02  
AnswerA possible explanation PinmemberShog913:32 16 Jul '02  
AnswerRe: some unneeded work? PinmemberChristian Tratz20:59 16 Jul '02  
GeneralRe: some unneeded work? PinmemberAndy Smith5:34 17 Jul '02  
GeneralRe: some unneeded work? PinmemberChristian Tratz8:01 17 Jul '02  
GeneralGreat. Only problem it will crash when resize to minimum width Pinmembershilin7:29 16 Jul '02  
GeneralFixed PinmemberChristian Tratz23:45 16 Jul '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 17 Jul 2002
Article Copyright 2002 by Christian Tratz
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid