Overview

I'm in the process of writing a Visual Studio template extension to automate the creation of Windows Communication Foundation components.  As part of the Wizard, I want to allow users to configure options based on various enumerations.  To help with this, I've developed a generic control that extends a ComboBox to manage a set of allowed values automatically.  This way, the same code can be used with any .NET enumeration type.

I've coded it as a generic type but it would be just as easy to use a runtime-provided type for the functionality.  Indeed, it already uses Reflection to check that the type is an enumeration.

Solution overview

The code derives a class from ComboBox with the following properties:

  • The control is a generic class that requires a value-type (struct) as a template parameter
  • The control can (optionally) allow non-selection using a Nullable<T> value
  • The control hides the internal Items collection to prevent unintentional manipulation of the collection
  • The control does not provide localisation or pretty names, but this is simple to add
  • The control can be used directly in place of an existing ComboBox control
  • Specific implementations can be created by derivation and used immediately

Class definition

The class definition is as follows:

class EnumerationSelectorControl<T> : ComboBox
    where T : struct
{
    public bool AllowNull { ... }
    public Nullable<T> Value { ... }
    public new ObjectCollection Items { get { throw new NotSupportedException(); } }
    
    public EnumerationSelectorControl() : base()
    {
        ...
    }

    private struct NullMember { ... }
    private struct EnumMember { ... }
}

As always, the implementation is the interesting part.

Firstly, note how the Items collection is hidden to the casual observer.

Secondly, the ComboBox Items collection is populated in the constructor using a combination of the NullMember and EnumMember types.  These types allow the separation of item value and item display.  The AllowNull property manages the existence of a NullMember item in the collection, and the constructor populates the collection with instances of EnumMember based on the output of Enum.GetNames(typeof(T)).

The implementation of the Value property is responsible for conversion between types and must take into account the value of AllowNull.  It is also responsible for selecting the appropriate item in the collection.

I'll leave the complete implementation as an exercise for the reader.  Once complete, you can define an enumeration-linked ComboBox as follows:

class ProtectionLevelControl :
  EnumerationSelectorControl<global::System.Net.ProtectionLevel>
{}

Versions

  • Microsoft .NET Framework 2.0

Metadata


Bookmark with :
Digg It! DZone StumbleUpon Technorati Reddit Del.icio.us Newsvine Furl Blinklist
posted @ Thursday, May 15, 2008 9:14 AM | in .NET Software Development

Comments

No comments posted yet.

Post Comment

Title *
Name *
Email
Url
Comment *  


Please add 7 and 7 and type the answer here: