How to bind Radio Buttons on an enum property?

Imagine this case:

public class MyBusinessClass

{

    public MyEnum Value { get; set; }

}

public enum MyEnum

{

    One,

    Two,

    Three,

    Four,

    Five

}

I want to generate dynamically my radio buttons and bind them on my business class.

Problem: How to bind each of my radio button on the business class?

  • I need one property per enum value to know if I must check the radio button.
    Horrible, I don’t want the BLL class interface to go bad on account of my UI.
  • I need an UI proxy which encapsulate my business object and add enum value properties.
    It’s better, but if my enum or, more probable, my MyBusinessClass class change, my code isn’t dynamic, and so I will need to change my proxy too.
  • I will keep the proxy idea but instead of creating the same properties in BLL and in my UI proxy, I will use PropertyDescriptors.

public class MyUIBusinessProxy<BusinessType> : ICustomTypeDescriptor

{

    public MyUIBusinessProxy(BusinessType myBusinessObject)

    {

        MyBusinessObject = myBusinessObject;

    }

 

    public BusinessType MyBusinessObject { get; private set; }

 

    #region ICustomTypeDescriptor Members

    AttributeCollection ICustomTypeDescriptor.GetAttributes()

    {

        return TypeDescriptor.GetAttributes(MyBusinessObject);

    }

    string ICustomTypeDescriptor.GetClassName()

    {

        return TypeDescriptor.GetClassName(MyBusinessObject);

    }

    string ICustomTypeDescriptor.GetComponentName()

    {

        return TypeDescriptor.GetComponentName(MyBusinessObject);

    }

    TypeConverter ICustomTypeDescriptor.GetConverter()

    {

        return TypeDescriptor.GetConverter(MyBusinessObject);

    }

    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()

    {

        return TypeDescriptor.GetDefaultEvent(MyBusinessObject);

    }

    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()

    {

        return TypeDescriptor.GetDefaultProperty(MyBusinessObject);

    }

    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)

    {

        return TypeDescriptor.GetEditor(MyBusinessObject, editorBaseType);

    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)

    {

        return TypeDescriptor.GetEvents(MyBusinessObject, attributes);

    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()

    {

        return TypeDescriptor.GetEvents(MyBusinessObject);

    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)

    {

        return GetPropertyDescriptors(attributes);

    }

    private PropertyDescriptorCollection GetPropertyDescriptors(Attribute[] attributes)

    {

        var propsColl = TypeDescriptor.GetProperties(MyBusinessObject, attributes, true);

        var props = new List<PropertyDescriptor>();

        foreach (PropertyDescriptor prop in propsColl)

        {

            props.Add(prop);

            if (prop.PropertyType.IsEnum)

            {

                var enumValues = Enum.GetValues(prop.PropertyType);

                var enumNames = Enum.GetNames(prop.PropertyType);

                for (int index = 0; index < enumValues.Length; index++)

                    props.Add(new IsEnumValuePropertyDescriptor(MyBusinessObject, prop.Name, prop.PropertyType, attributes, enumNames[index], (int)enumValues.GetValue(index)));

            }

        }

        return new PropertyDescriptorCollection(props.ToArray());

    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()

    {

        return GetPropertyDescriptors(null);

    }

    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)

    {

        return MyBusinessObject;

    }

    #endregion ICustomTypeDescriptor Members

 

    private class IsEnumValuePropertyDescriptor : PropertyDescriptor

    {

        private BusinessType _businessObject;

        private string _propertyName;

        private Type _propertyType;

        private int _value;

 

        public IsEnumValuePropertyDescriptor(BusinessType businessObject, string propertyName, Type propertyType, Attribute[] attr, string valueName, int value)

            : base (propertyName + “Is” + valueName, attr)

        {

            _businessObject = businessObject;

            _propertyName = propertyName;

            _propertyType = propertyType;

            _value = value;

        }

 

        public override bool CanResetValue(object component)

        {

            return false;

        }

        public override Type ComponentType

        {

            get { return typeof(BusinessType); }

        }

        public override object GetValue(object component)

        {

            return (int)(typeof(BusinessType).GetProperty(_propertyName).GetValue(_businessObject, null)) == _value;

        }

        public override bool IsReadOnly

        {

            get { return false; }

        }

        public override Type PropertyType

        {

            get { return typeof(bool); }

        }

        public override void ResetValue(object component)

        {

        }

        public override void SetValue(object component, object value)

        {

            if ((bool)value)

                typeof(BusinessType).GetProperty(_propertyName).SetValue(_businessObject, _value, null);

        }

        public override bool ShouldSerializeValue(object component)

        {

            return false;

        }

    }

}


And now, I can easily do this:


foreach (var enumName in Enum.GetNames(typeof(MyEnum)))

{

    var rb = new RadioButton();

    myFlowLayoutPanel.Controls.Add(rb);

    rb.Text = enumName;

    rb.DataBindings.Add(“Checked”, myUIBusinessProxy, “ValueIs” + enumName);

}

This entry was posted in 7671, 7679. Bookmark the permalink.

2 Responses to How to bind Radio Buttons on an enum property?

  1. Steve says:

    Thanks a bunch for this amazing sample code. I’ve actually written it as a base class that I derive my presentation models from so that I don’t have to re-type everything for every PM in my MVC templated code.

    Again, many thanks! This is the best code snippet out there for this situation.

  2. ahole ahole says:

    rofl what shit for brains posted this crapola
    hey mat what the shit your dumb ahole name is rofl your suppose to provide source code for download but since your a dumb shit sob you and this posting is crapola there is no source code rofl

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>