C# – How to create a custom collection editor form for use with the property grid

ccollectioneditornetpropertygrid

I am trying to incorporate a property grid control with a class that has a list/collection of another class as one of the properties. Lets call them class A and the list would be containing class B for reference.

I was wanting to incorporate a form that had two list boxes. The list box on the left would contain a list of all of class B's in my program that are not currently in the list on the right. The list on the right would contain all of the class B's that are currently associated with class A. I want buttons in between to move items between the two lists.

This would be easy to design, but I'm not sure exactly how to set up the form to be used as the collection editor.

Can anyone point me in the right direction?

And also, how can I go about having setting up a drop down for a property that contains a list of id's to select from if anyone could point me in the direction for accomplishing this as well.

Best Answer

Okay, I was finally able to track down how to accomplish this.

I was attempting to create a custom CollectionEditor.CollectionForm which was close to what I needed to do, but it wasn't quite the right direction.

First of all, create a regular Windows Form which includes your GUI for editing your collection. Then just include button/buttons which return a DialogResult in the Form.

Now the key to accomplishing what I was looking for is not a CollectionEditor.CollectionForm as I had thought would be the correct approach, but rather a UITypeEditor.

So, I created a class that inherited from the UITypeEditor. Then you simply flesh it out as such:

public class CustomCollectionModalEditor: UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        if (context ==null || context.Instance == null)                
            return base.GetEditStyle(context);

        return UITypeEditorEditStyle.Modal;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService editorService;

        if (context == null || context.Instance == null || provider == null)
            return value;

        editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

        CForm CollectionEditor = new CForm();

        if (editorService.ShowDialog(CollectionEditor) == System.Windows.Forms.DialogResult.OK)
            return CollectionEditor.Programmed;

        return value;
        //return base.EditValue(context, provider, value);
    }
}

The key parts to take note of, are the functions GetEditStyle and EditValue. The part responsible for firing-off the Form you created to edit your collection, is in the EditValue override function.

CForm is the custom collection editor form I designed in this test to edit the collection. You need to fetch the IWindowsFormsEditorService associated with the IServiceProvider and simply call the .ShowDialog(formVariable) of the IWindowsFormsEditorService in order to show the form you designed to edit the collection. You can then catch the returned DialogResult value from your Form and perform any custom handling that you require.

I hope this helps someone out as it took me quite a bit of digging to determine the right way to incorporate this.