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

Extended ListView

By , 13 Jun 2006
 

Sample Image - EXListView.gif

Introduction

There are many examples here on The Code Project that enhance the functionality of the ListView. I was looking for a way to display and edit multiple images on subitems and be able to sort the ListView by date, number, string, and images, but I wasn't able to find one that could do that. The subitems also had to be editable - either by a textbox, or by a user defined control. Finally, I wanted to be able to add controls to the subitems and provide some kind of "boolean" columns. The subitems that are in such a boolean column will be able to show two values - true or false - that can be represented by two images. If you set the Editable property to true, the user can click such a subitem and the value switches.

Background

Previously, you had to use the Win32 API to accomplish the above. Now, with version 2.0 of the .NET framework, this can be much easily done with the concept of ownerdraw. If the OwnerDraw property of a ListView is set to false, you can do all of the drawing of the ListView yourself. In this EXListView class, I use ownerdraw extensively. Although using the Win32 API is faster than using ownerdraw from the .NET framework, this ListView is still fast, even with 1000 items with subitems that contain multiple images.

Using the code

The code accompanying this article is the EXListView class, the EXComboBox class, and a simple form that uses these in a form. I added an executable, but you can easily compile it yourself with the command csc /t:winexe /r:System.Windows.Forms.dll EXListView.cs EXComboBox.cs MyForms.cs - the compiler csc.exe can be found on Windows XP in C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\.

Defining an instance and adding columns

If you have created an instance of the EXListView class (for example: EXListView exlstv = new EXListView()), you can begin adding columns. There are three different types of columns: EXColumnHeader, EXEditableColumnHeader (whose subitems can be edited by a default TextBox or a user defined control), and the EXBoolColumnHeader (whose subitems can only show true or false and can optionally be edited).

For example, to get a column header that can be edited by a default TextBox, you do:

EXEditableColumnHeader editcol = 
                  new EXEditableColumnHeader("Movie");

If you want to specify a control by which the subitems can be edited, you do:

// define a control to edit the subitems of this column
ComboBox cmbx = new ComboBox();
cmbx.Items.AddRange(new string[] {"1", "2", "3", "4"});
// define a columnheader whose subitems can be edited
EXEditableColumnHeader editcol = 
     new EXEditableColumnHeader("Position");
// add the combobox to the column
editcol.MyControl = cmbx;

A boolean column:

EXBoolColumnHeader boolcol = new EXBoolColumnHeader("OK");
// if you want the users to be able to edit
// the boolean values, set the Editable property to true
boolcol.Editable = true;
// specify an image for each of the values
boolcol.TrueImage = Image.FromFile("true.png");
boolcol.FalseImage = Image.FromFile("false.png");

Add (sub)items to the EXListView

A regular ListViewItem:

EXListViewItem lstvitem = new EXListViewItem("Pete");

Items and subitems that can show images have a property MyValue that can hold the real textual value of the (sub)item. This can be handy if you don't want to show text, but need some kind of value, for example, to insert into a database.

An item that can show only one image:

EXImageListViewItem imglstvitem = new EXImageListViewItem();
imglstvitem.MyImage = Image.FromFile("Pete.jpg");
imglstvitem.MyValue = "Pete";

An item that can show multiple images:

EXMultipleImagesListViewItem mimglstvitem = 
        new EXMultipleImagesListViewItem();
// define arraylist with all the images
ArrayList images = new ArrayList(new object[] 
          {Image.FromFile("Pete.jpg"), 
          Image.FromFile("man.png")});
mimglstvitem.MyImages = images;
imglstvitem.MyValue = "Pete the man";

The same way, you can add subitems to the EXListView. Please see the EXListView class for more information.

Use the EXComboBox to edit items with images

The source also contains an extended ComboBox class - the EXComboBox class: this is a combobox that can hold images. You can use this combobox to edit (sub)items with images in the EXListView.

// create an EXListView
EXListView lstv = new EXListView();
// craete an EXComboBox
EXComboBox excmbx = new EXComboBox();
excmbx.MyHighlightBrush = Brushes.Goldenrod;
excmbx.ItemHeight = 20;
// add images to the combobox and the values
excmbx.Items.Add(new EXComboBox.EXImageItem(
       Image.FromFile("music.png"), "Music"));
excmbx.Items.Add(new EXComboBox.EXImageItem(
     Image.FromFile("comedy.png"), "Comedy"));
excmbx.Items.Add(new EXComboBox.EXMultipleImagesItem(
       new ArrayList(new object[] 
       {Image.FromFile("love.png"), 
       Image.FromFile("comedy.png")}), 
       "Romantic comedy"));
// add this combobox to the first columnheader
lstv.Columns.Add(new EXEditableColumnHeader("Genre", 
                                       excmbx, 60));

Add and remove images during runtime

If you want to add or remove images during runtime, you can just set the MyImage property to null, or, in the case of a multiple-images (sub)item, use the ArrayList methods, such as Add() and RemoveAt(). Examples:

If you want to remove the second image from an EXMulitpleImagesListViewSubItem (second column) in the third row, you do:

EXMultipleImagesListViewSubItem subitem = 
   lstv.Items[2].SubItems[1] 
   as EXMultipleImagesListViewSubItem;
subitem.MyImages.RemoveAt(1);
lstv.Invalidate(subitem.Bounds);

You must invalidate this rectangle yourself.

Adjusting the heights of rows

Because all the drawing is done in the owner-draw events, the SmallImageList property is only used to show the up and down arrows in the column headers and not to show images in the ListViewItem. To adjust the row height, you assign an ImageList and set the Size to the appropriate size. This is a dirty hack, but the only way I could do it. If you can find another way - please let me know.

Adding controls

To add a control to a subitem, create a EXControlListViewSubItem, then create the control, add the EXControlListViewSubItem to the listviewitem, and at last, add the control to the EXControlListViewSubItem with the EXListView method AddControlToSubitem:

EXListViewItem item = new EXListViewItem("Item 1");
EXControlListViewSubItem cs = new EXControlListViewSubItem();
ProgressBar b = new ProgressBar();
b.Minimum = 0;
b.Maximum = 1000;
b.Step = 1;
item.SubItems.Add(cs);
lstv.AddControlToSubItem(b, cs);

Points of interest

There is, at this point, an irritating bug in the EXListView class: when you move your mouse pointer into the ListView from left to right, the DrawItem event will be fired, but accompanied by the DrawSubItem event. So, the ListViewItem will be repainted, but the subitems will not. If the content of the ListViewItem (represented by the first subitem) is larger than the column, the content falls over the neighboring subitems.

History

  • Created on 9 February 2006.
  • Updated code and article: now you can edit columns with images as well - 15 February 2006.

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

Michiel van Eerd
Netherlands Netherlands
Member
...to be continued.

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.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralSome Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version [modified]membercinamon30 Dec '07 - 6:26 
well this is certainly a very nice control,
I have made a number of improvements to the original version,
 
-using generic list<t> instead of arraylist everywhere - there is a lot of arraylists used, this conversion alone improved performance a lot
 
-owerdraw bug, when moving with the mouse over columns from left to right you will see draw errors depending on the width of your column & content, I have fixed those , even for cases when you have 1 or multiple images
 
- column reordering- reorder columns at runtime and try editing a boolean column, you can't because the mousedouble click routine in the original code doesnt check if the columns have been reordered by user at run time, I fixed that, now columns can be reordered as you wish and editing works
 
- draw speed with images.. test this add 5 columns with images in a couple of subitems, also add 1 column that has 4 or 5 multipleimages within same subitem - now add ~100 or more lines to the listview, it draws but it sluggish, slow - because every time you want to draw an image, an actual system.drawing.image is passed into the property of the listviewitem, taking up huge resources when you have more then 100 lines or so. I have re-written all image routines to take a integer index and an Imagelist PER column (each column can have its own imagelist if you want) and only the index is passed into the draw function and only at the last minute before the dodraw function the image is extracted, that way all the images resources are cached and managed by the imagelist which does a better job - result my version draws 500 lines with 7 columns and 10 subimages (16x16 32bit) over 5 times faster then the original version (my unscientific tests show ~520 ms for original version and 95ms for the indexed image version!) - this makes a HUGE difference to the control when you scroll around or do anything
 
there is a flickering issue which I am still working on, it has to do with the SendMSG / WM_ERASEBKG API call, Im still looking into some good options for that, but even as it is, do to much much faster performance the flickering in the original control is less noticeble
 
I have also converted the complete code to VB, too bad the author has abondoned work on this great control, you did a great job and what I have done is very little to your work,
 
If anyone wants my VB version just leave your email here and I'll sent it
thanks
 
modified on Sunday, January 20, 2008 12:15:36 PM

GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberJason Cz.25 Feb '08 - 9:52 
jczarni@gmail.com - C# version please. Thanks for your work!
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembermanna2 Mar '08 - 3:44 
Me too please, C# if possible: manna6@hotmail.com. thanks!
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberpizzapieguy11 Mar '08 - 15:54 
I'd like a copy also. C# version please. zach.robinson@gmail.com Thanks a bunch!
QuestionRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembertamagotchi1 Apr '08 - 5:01 
Me too please, I'm interesting in the bug number 2, ownerdraw bug then moving over columns from left to right... tama01fr@hotmail.com thank you so much...
 
One more thing, enabling HideSelection seems to cause all the lines to be marked as Selected in the DrawSubItem method. I cannot find a workaround to keep only the selected line highlighted when leaving the control. Can you help ? thank you !
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberCraig Neuwirt26 Apr '08 - 6:29 
Great Stuff! Could you please send me the C# version @ cneuwirt@gmail.com
 
thanks,
craig
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberelcampion24 Jun '08 - 17:44 
please send your vb code to leorenguero@yahoo.com.ar
 
thank you very much
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberGod.Ghost2 Aug '08 - 23:56 
Can you send me a copy of C# version? Smile | :)
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberteixeirafms11 Aug '08 - 5:11 
Can you send me the C# version : teixeirafms (at) gmail.com
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberyngie15 Aug '08 - 12:19 
I would love to see both versions, C# and VB. Please send them to yngie@treebiter.com. Thank you! Wink | ;)
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberchenpusn29 Aug '08 - 17:41 
pchen@ethos.com.cn
 
Can you send me a C# copy? Thanks.
 
chenpusn

GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembermelens22 Oct '08 - 23:17 
Great Work, please could you send me the C# version to mark.huston@apv.com
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberMember 57525479 Dec '08 - 2:29 
hi
 
vb version please
 
zukk3r@web.de
 
thanks
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberfrobozzdamad11 Feb '09 - 3:40 
I'd love the VB version with your fixes. tspre (at) yahoo.com
 
Thanks much!
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembershoorrock16 Feb '09 - 11:57 
I'm interested too.
 
shorrockt at bellsouth dot net
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberpqingfeng@gmail.com24 Apr '09 - 16:35 
I want the VB version. Thanks.
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberCannabyss4 May '09 - 18:28 
Could you send me the code too, arsedestroyer@yandex.ru . Thanks.
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembersanndeb30 Jun '09 - 19:29 
C# Or VB .Net Version Please... sanndeb@yahoo.co.in
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembermn7593021 Jul '09 - 22:41 
Hello.
Can you please send me the c# version of this grate control??
 
info@r-data.no
 
Best regards SJR Blush | :O
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembercinamon22 Jul '09 - 3:17 
The modified VB version is here, if anyone has a better place to share with more people go ahead,
 
this link will die out after 10 downloads
 
http://rapidshare.com/files/258714379/EX_ListView_VB.zip.html[^]
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembervw_dev9 Oct '09 - 4:22 
Please send me the VB Version. Thx in advance. wagner@omnisecurity.lu
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberBug Me Not20 Oct '09 - 9:03 
Please send me the C# version... henry4256 at gmail.com. Thanks!!!
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembertomasmalovic7 Apr '10 - 9:46 
hi,
 
if you are still tracking this thread, could you please send your C# source to tomas_malovic@centrum.sk? Many thanks in advance
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberMember 46958593 May '10 - 22:33 
If you are still tacking this, please also send me the VB.net version to my e-mail hsuyu.cheng@gmail.com Thank you in advance.
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmembervideoed9 Jun '10 - 20:27 
Would be nice to have the VB version. pr3dr@gmx.net, Thanks.
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberlazartefederico2 Sep '10 - 5:45 
Hello.
Can u send to lazartefederico@hotmail.com.ar please?
Thanks a lot.
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version Pinmemberhammer17 Sep '10 - 20:09 
Hi, nice work Smile | :) I would like a copy in c#, can you please send it to hammer_mortensen@hotmail.com. /Pete
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberJohnno7420 Oct '10 - 13:06 
Hi,
Can you please send the VB.Net version to john.sinclair@gmail.com
 
Hope you are still watching this thread - can I suggest just upload the code to drop.io or somewhere and post the link?Thumbs Up | :thumbsup:
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version PinmemberPhillip Cohen30 May '11 - 6:42 
Could you send the C# version to me too? Thanks!
 
philltopia@gmail.com
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version [modified] Pinmembertojckim27 Feb '12 - 17:45 
Great~~.
Can I get a copy of C# version?
 
tojckim(at)gmail.com
 
I'm a newbie in C#.
Please this will save my life.
 
Thanks.
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version [modified] Pinmemberplaguebreath7 Jun '12 - 22:19 
I'd love to see the piece of code for fix the stuff too, please could you send me the c# code ?
 
ryosaebaxyz77[at]hotmail.com
GeneralRe: Some Improvements - converted all Arraylists to Generic List, ImageDraw Speed, Column Reordering and VB version [modified] Pinmembersyst3ms12 Jul '12 - 11:47 
I know this post was years ago by you on codeproject - but i was wondering if you still had the vb version of extended listview? I would very much like to study it and learn from it - as the default listview control is very limited.
my email: tjs_messenger@hotmail.com

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 13 Jun 2006
Article Copyright 2006 by Michiel van Eerd
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid