65.9K
CodeProject is changing. Read more.
Home

WPF Enumeration Data Provider

starIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

1.00/5 (1 vote)

Feb 4, 2013

CPOL
viewsIcon

13661

WPF Enumeration Data Provider

In my recent adventures creating activity designers (Workflow Foundation 4+), I needed a way to bind a ComboBox with an enumeration and didn't want to manually wire up events in the code behind. Fortunately, I found some examples on how to use an ObjectDataProvider. This worked great, but I realized the setup was more than I wanted to do every time I needed an enumerated bound ComoBox and came up with my own EnumerationDataProvider. In addition to simplifying the setup, I added the following features / customizations...

  • Inherits from ObjectDataProvider and sets up the properties and parameters for you.
  • Automatically associate the None enumeration value to a blank value.
  • Allows you to override the None value and None display value.
  • Sorts the enumerations values by name.

For those who are not aware, custom activity designers are created essentially using WPF.
Here is the implementation...

public class EnumerationDataProvider : ObjectDataProvider
{
    public Type EnumerationType { get; set; }

    public string NoneValue { get; set; }

    public string NoneDisplayValue { get; set; }

    public EnumerationDataProvider()
    {
        this.MethodName = "GetEnumerations";
        this.ObjectType = typeof(EnumerationHelper);
    }

    protected override void EndInit()
    {
        this.MethodParameters.Clear();
        this.MethodParameters.Add(this.EnumerationType);
        this.MethodParameters.Add(this.NoneValue);
        this.MethodParameters.Add(this.NoneDisplayValue);

        base.EndInit();
    }

    private static class EnumerationHelper
    {
        private const string NoneDefaultValue = "None";
        private const string NoneDisplayDefaultValue = "";

        public static IDictionary<object, string> GetEnumerations(
            Type enumType, string noneValue, string noneDisplayValue)
        {
            // Setup defaults if none exists.
            if (string.IsNullOrWhiteSpace(noneValue)) noneValue = NoneDefaultValue;
            if (string.IsNullOrWhiteSpace(noneDisplayValue)) noneDisplayValue = NoneDisplayDefaultValue;

            IDictionary<object, string> items = new Dictionary<object, string>();

            // Find the None enumeration value.
            string noneStringValue = (from n in Enum.GetNames(enumType) 
                                        where string.Compare(n, noneValue, 
                                              StringComparison.OrdinalIgnoreCase) == 0 
                                        select n).FirstOrDefault();

            bool hasNoneValue = !string.IsNullOrWhiteSpace(noneStringValue);

            object noneEnumerationValue = null;
            if (hasNoneValue)
            {
                // Parse the None value if it exists and add it as the first item.
                noneEnumerationValue = Enum.Parse(enumType, noneStringValue, true);
                items.Add(noneEnumerationValue, noneDisplayValue);
            }

            // Select all enumeration values where not equal to the None value and order by 
            // the enumeration value name.
            var orderedEnums = from v in Enum.GetValues(enumType).Cast<object>() 
                                where !v.Equals(noneEnumerationValue) 
                                orderby Convert.ToString(v) select v;

            foreach (var value in orderedEnums)
                items.Add(value, Convert.ToString(value));

            return items;
        }
    }
}