Click here to Skip to main content
Click here to Skip to main content

An auto-resize C# ListBox

, 16 Jul 2002
Rate this:
Please Sign up or sign in to vote.
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

Share

About the Author

Christian Tratz
Web Developer
Germany Germany
If you are not living on the edge you are wasting space Wink | ;)

Comments and Discussions

 
Generaladding to the list next line Pinmemberjinfrics28-Jun-09 20:22 
GeneralRe: adding to the list next line Pinmemberyuzaihuan8-May-14 4:30 
GeneralTriggering ListBox.Measureitem PinmemberThe_Mega_ZZTer22-Aug-05 11:18 
GeneralRe: Triggering ListBox.Measureitem Pinmembernicorac5-Nov-08 23:42 
GeneralMouse Wheel problem Pinmemberadi8816-Aug-04 23:02 
GeneralAlso, some few advices... Pinmemberadi8816-Aug-04 23:26 
GeneralRe: Also, some few advices... PinmemberChristian Tratz7-Aug-04 0:27 
GeneralRe: Also, some few advices... PinmemberLelieveld25-Aug-04 2:32 
GeneralRe: Mouse Wheel problem Pinmemberlinlinzongzong217-Apr-05 5:29 
GeneralSome adjustments PinmemberLelieveld17-Jun-04 0:08 
GeneralEasier way to do this PinmemberJohan Danforth13-Jan-04 23:04 
GeneralThis code Even not Compiling in VS 2003 PinmemberSYSDBA9-Jan-04 5:03 
GeneralRe: This code Even not Compiling in VS 2003 PinmemberChristian Tratz11-Jan-04 7:21 
GeneralRe: This code Even not Compiling in VS 2003 PinmemberLelieveld16-Jun-04 23:57 
GeneralFixed a bug computing AutoScrollMinSize PinmemberMike Staley6-Oct-02 21:05 
GeneralRe: Fixed a bug computing AutoScrollMinSize Pinmemberjunkmegently20-Nov-02 13:56 
GeneralRe: Fixed a bug computing AutoScrollMinSize PinmemberMatt Whitfield7-Sep-08 13:00 
Questionsome unneeded work? PinmemberAndy Smith16-Jul-02 8:50 
AnswerA possible explanation PinmemberShog916-Jul-02 14:32 
AnswerRe: some unneeded work? PinmemberChristian Tratz16-Jul-02 21:59 
GeneralRe: some unneeded work? PinmemberAndy Smith17-Jul-02 6:34 
GeneralRe: some unneeded work? PinmemberChristian Tratz17-Jul-02 9:01 
GeneralGreat. Only problem it will crash when resize to minimum width Pinmembershilin16-Jul-02 8:29 
GeneralFixed PinmemberChristian Tratz17-Jul-02 0:45 

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.

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