Extending the DropDownList to Support Enums
page 3 of 6
by Steven Smith
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 33016/ 116

Creating a Generic Enum DropDownList

Now that we’ve written a bunch of code to show how anybody can do this to a stock DropDownList control, let’s roll all of this code into a single reusable control, the EnumDropDownList.  One additional requirement we’ll add to this control is that it optionally include a ListItem that simple displays “All” and has no associated enum value.  We’ll use this when the DropDownList is being used to display filters on search results or reports, and in this case the “All” value will mean that we don’t want to filter by this enum.  Similarly, to make our filtering easier, we’ll also include a nullable integer property, SelectedIntegerValue, since the data access layer is going to expect integer values for the statuses we choose to filter on (or null if none).  The control will include the GetEnumDataSource<T> method shown earlier, and of course this could be refactored out into a separate utility class where it would make more sense.  I’ve included it in EnumDropDownList to make the sample easier to follow.  The complete source for EnumDropDownList is shown in Listing 6.

Listing 6: EnumDropDownSource

public class EnumDropDownList<T> : DropDownList where T : struct
{
    private bool _showAllOption = true;
    public bool ShowAllOption
    {
        get
        {
            return _showAllOption;
        }
        set
        {
            _showAllOption = value;
        }
    }
    public new T? SelectedValue
    {
        get
        {
            if (String.IsNullOrEmpty(this.SelectedItem.Text))
            {
                return null;
            }
            return (T)Enum.Parse(typeof(T), this.SelectedItem.Text);
        }
    }
    public int? SelectedIntegerValue
    {
        get
        {
            if (ShowAllOption && this.SelectedIndex == 0)
            {
                return null;
            }
            if (String.IsNullOrEmpty(this.SelectedItem.Text))
            {
                return null;
            }
            return (int)Enum.Parse(typeof(T), this.SelectedValue.ToString());
        }
    }
 
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        if (typeof(T).BaseType != typeof(Enum))
        {
            throw new ArgumentException("Type T must inherit from System.Enum.");
        }
        BindData();
    }
 
    protected void BindData()
    {
        this.DataSource = GetEnumDataSource<T>();
        this.DataTextField = "Key";
        this.DataValueField = "Value";
        this.DataBind();
        if (ShowAllOption)
        {
            this.Items.Insert(0, new ListItem("All"""));
        }
    }
 
    public static SortedList<stringint> GetEnumDataSource<T>() where T : new()
    {
        Type myEnumType = typeof(T);
        if (myEnumType.BaseType != typeof(Enum))
        {
            throw new ArgumentException("Type T must inherit from System.Enum.");
        }
 
        SortedList<stringint> returnCollection = new SortedList<stringint>();
        string[] enumNames = Enum.GetNames(myEnumType);
        for (int i = 0; i < enumNames.Length; i++)
        {
            returnCollection.Add(enumNames[i],
                (int)Enum.Parse(myEnumType, enumNames[i]));
        }
        return returnCollection;
    }
}

Now to use this control, unfortunately you can’t simply add markup to the ASPX page.  Some options were discussed by Mikhail at Microsoft but I can’t find that anything was ever implemented up through ASP.NET 3.5.  Thus, you can only instantiate this control from your C# or VB code, and then add it to the page using a Placeholder control or similar technique.  This is fairly minor, however, and the resulting code in the page’s codebehind is shown in Listing 7.  PlaceHolder1 is defined on the page where we want the DropDownList to be shown.

Listing 7: Rendering the Control in a PlaceHolder

protected EnumDropDownList<ProposalStatus> ProposalStatusDropDownList1;
protected override void OnInit(EventArgs e)
{
  base.OnInit(e);
  ProposalStatusDropDownList1 = new EnumDropDownList<ProposalStatus>();
  this.PlaceHolder1.Controls.Add(ProposalStatusDropDownList1);
}

View Entire Article

User Comments

Title: Great   
Name: Suraj
Date: 2008-12-04 1:30:52 AM
Comment:
great helped immensly
Title: Great   
Name: Willy AF
Date: 2008-02-02 10:01:36 PM
Comment:
Great work, I will wait for the next trick, Very helpful,,,
Thanks
Title: Greate tips   
Name: nguyen letan
Date: 2008-02-02 7:31:09 AM
Comment:
Your article is very helpful for me. Thanks!
Title: Great Trick   
Name: s.k.shivaprasad
Date: 2008-01-31 4:47:50 AM
Comment:
Great work. I spent a lot of time trying to figure this out myself. It is kind of annoying that ASP.NET doesn't support declared generic controls. That would be a great improvement.good...
Title: Great Article   
Name: Joydip
Date: 2007-12-10 12:39:26 PM
Comment:
Hi Steve, this is an excellent article. This will help the readers a lot. Awesome!

Thanks,

Joydip

Author, Data Presentation Controls Essentials (PacktPub)
Title: Really useful   
Name: Uday D
Date: 2007-12-05 3:42:07 AM
Comment:
Very helpful link. Thanks.
Title: Great Trick   
Name: Brendan
Date: 2007-12-04 9:53:13 AM
Comment:
Great work. I spent a lot of time trying to figure this out myself. It is kind of annoying that ASP.NET doesn't support declared generic controls. That would be a great improvement.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-11-29 8:50:27 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search