torsdag 9. juni 2011

UITypeEditor

When you add a property to a class, the Visual Studio developer environment automatically adds this to the properties pane as a string.

Sometimes we would like a choose this from a graphical user interface. This can be done by using UITypeEditor. I've created a property in my class and wanted the user to be able to choose a type from the same assembly (which implements IHandler). Here is the code:

namespace Birol.UIType
{
    internal class InterfaceEditor : UITypeEditor
    {
        //we have to override EditValue method to tell Visual Studio how to behave on edit.
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            Type returnValue = null;
            var service = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
            if (service != null)
            {
                var types = new List();
                
                var a = Assembly.GetExecutingAssembly();
                var types = a.GetTypes();

                //we loop through each type and check if it implements IHandler
                foreach (var t in types)
                {
                    if (typeof(IHandler).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface)
                    {
                        types.Add(t);
                    }
                }

                //We display a listbox to the user with the values he/she can choose from.
                var list = new ListBox();
                list.Click += new EventHandler((sender, args) => service.CloseDropDown());
                list.Items.AddRange(types.ToArray());
                service.DropDownControl(list);
                if (list.SelectedIndices.Count == 1)
                {
                    returnValue = list.SelectedItem as Type;
                }
            }
            return returnValue;
        }

        //override to tell visual studio which editstyle to use.
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.DropDown;
        }
    }
}

And here is how you create the property:

[Browsable(true),
         Editor(typeof (InterfaceEditor), typeof (UITypeEditor)),
         Category("Behavior"),
         DescriptionAttribute("The name of the class that should be executed when clicked.")]
        public Type Executer { get; set; }

Here is the result:

Ingen kommentarer:

Legg inn en kommentar