简体   繁体   中英

Is using a custom TypeDescriptionProvider still the only way around using generic forms in the designer for VS2012?

I have forms that inherit from a generic base form and execute as expected however they dont display in the designer.

Ive hunted around the net and found some questions here on SO and some blog articles that say to use a custom TypeDescriptionProvider. The articles im finding are circa 2008-2010.

Using Visual Studio Whidbey to Design Abstract Forms

Generic forms and VS designer

Is this still the way to go using VS2012, .NET 4.0 in Sept 2013?

Many people claim the same mechanism using TypeDescriptionProvider that works for abstract base classes should work for generic ones, however I have yet to come across anyone who actually got it working.

I for one spent hours trying to get the TypeDescriptionProvider-based solution to work for generic base classes, however unlike the abstract base case, the designer doesn't seem to try using the specified type descriptor provider (verified by using one VS instance to debug another VS instance's designer).

It may be possible to get it working, but the attribute solution doesn't work out-of-the-box in the generic case. Even the author of the OP's referenced article (which seems to have been copied verbatim from here ) acknowledges in the comments that he hasn't tested it for generics.

Anyone had any luck?

Not a solution that works all the time but this will do for most part:

class GenericControlDescriptionProvider : TypeDescriptionProvider
{
    public GenericControlDescriptionProvider()
        : base(TypeDescriptor.GetProvider(typeof(ContainerControl)))
    {
    }

    public override Type GetReflectionType(Type objectType, object instance)
    {
        if (objectType.IsGenericType)
        {
            return objectType.BaseType;
        }

        return base.GetReflectionType(objectType, instance);
    }

    public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
    {
        if (objectType.IsGenericType)
        {
            objectType = objectType.BaseType;
        }

        return base.CreateInstance(provider, objectType, argTypes, args);
    }
}

All I am checking for is if the target type is generic, if so use its base class. The assumption here is that the base class is a proper instantiable class for the designer. An example:

[TypeDescriptionProvider(typeof(GenericControlDescriptionProvider))]
public abstract class FormBase<TViewModel> : Form

Tested for VS 2017, .NET 4.5.2. The catch is solution (read the presentation project) has to be built once for the lifetime of the VS process. Every time you start VS, you need to build once, that's all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM