Click here to Skip to main content
15,881,600 members
Articles / Desktop Programming / Windows Forms
Tip/Trick

Simple Custom Collection Designer Support

Rate me:
Please Sign up or sign in to vote.
4.57/5 (8 votes)
15 Nov 2015CPOL3 min read 10.1K   253   3   3
The simplest solution for adding a custom collection of custom objects to the designer

Standard Collection Editor

Introduction

Add design-time support for your custom collection of custom objects in 10 minutes.

The sample above adds a MyList of ImageEntry objects to a Usercontrol, and displays them one at a time in a picturebox (using a timer). It took me a full 20 minutes to write that entire program.

Background

For my image transitions project, I needed to be able to pre-load a collection of images at design time. Originally, I did this by creating a TypeConverter for the ImageEntry type, and loading that into the list. This was difficult to implement, and really never did work particularly well (sometimes I was losing the images that had been loaded, and I never did figure out why).

Recently, I needed to upgrade the project so that the list of images was thread-safe, and after creating this thread-safe list of ImageEntry objects (TList<ImageEntry>), I just could not get them into the designer. All the articles I read were talking about creating custom UITypeEditor forms, creating full implementations of ITypeConveter objects or implementing IComponent on my object, etc. They were all very complicated.

Eventually, I got to the bottom of what everyone was saying, and why, and came up with this.

Using the Code

There are three things to do to enable your list to appear in the designer:

  1. Prepare the list
  2. Prepare the content type
  3. Decorate the property

Preparing the List

Most articles describing the creation of design-time collections support inherited their collections from CollectionBase. This is all well and good, but not always appropriate for any number of reasons. Your collection may already be inherited from another object, and multi-inheritance is not permitted. Or perhaps, you want your internal collection to have more features than the CollectionBase offers, which was the case with my TList.

The bottom line is you have two choices here. First, you can inherit from CollectionBaseif that works for you, or second, you need to implement the non-generic IList interface. This second option was the thing that had me stuck for ages, as none of the existing articles mentioned it. My TList implemented IList<ImageEntry>, ICollection<ImageEntry> and IEnumerable<ImageEntry>, but when the collections form appeared in the designer, I still could not add my ImageEntry objects to the collection.

Implementing the non-generic IList was easy - I just passed all the calls through to the Generic implementation. Took me all of 2 minutes.

Preparing the Content Type

Once again, most of the existing articles go into a lot of detail about creating a TypeConverter for your collection's content type. I found this very difficult to get right, and spent hours just playing around with this to get it working with some semblance of usability. They all seem to glance over the fact that you can alternatively implement IComponent to have your object appear in the designer. IComponent is very easy to implement (one field and one property is all that's needed), or even simpler than that, if possible, you can inherit your object from Component, and that implementation is done for you.

The only problem with using the IComponent is that your object tends to appear all over the place in the designer. This is solvable, however, with one line of decoration mentioned below.

Decorating the Property

When adding the collection as a property of your control, there are 2 obligatory attributes required - the [DesignerSerializationVisibility(DesignerSerializationVisibility.Content) and the Editor(typeof(CollectionEditor), typeof(UITypeEditor)) attributes. Once that is done, everything just works.

In order to prevent every instance of your content appearing in the designer, you just need to decorate your object with the DesignTimeVisible(false) attribute.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Australia Australia
Been programming for 40 years now, starting when I was 13 on DEC PDP 11 (back in the day of paper tape storage, and hex switch boot procedures). Got right into micro-computers from an early age, with machines like the Dick Smith Sorcerer and the CompuColor II. Started CP/M and MS-DOS programming in the mid 1980's. By the end of the '80's, I was just starting to get a good grip on OOP (Had Zortech C++ V1.0).

Got into ATL and COM programming early 2002. As a result, my gutter vocabulary has expanded, but it certainly keeps me off the streets.

Recently, I have had to stop working full time as a programmer due to permanent brain damage as a result of a tumour (I just can't keep up the pace required to meet KPI's). I still like to keep my hand in it, though, and will probably post more articles here as I discover various tricky things.

Comments and Discussions

 
QuestionHow about item events? Pin
Member 1294661514-Dec-17 23:52
Member 1294661514-Dec-17 23:52 
BugBug Pin
Member 1294661514-Dec-17 3:34
Member 1294661514-Dec-17 3:34 
GeneralMy vote of 5 Pin
George Jonsson15-Nov-15 17:12
professionalGeorge Jonsson15-Nov-15 17:12 

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

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