1

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?

Community
  • 1
  • 1
rism
  • 11,932
  • 16
  • 76
  • 116
  • 'Fraid so, the issues still exist as the designer has had no love for a while. Which reminds me, I need to update that blog post as the `TypeDescriptionProvider` solution wasn't around when I first came across it. The solution I settled on involved a surrogate type that resolved the generic argument in the designer. – Adam Houldsworth Sep 11 '13 at 13:18
  • Thanks i know its a crappy question that's hard to answer in 5 characters or more but i wanted to check. – rism Sep 11 '13 at 13:20
  • Can you add some links to this in your question? I'm curious about the `TypeDescriptionProvider` solution. – Adam Houldsworth Sep 11 '13 at 13:20
  • Lol i was just going to ask you for links about about your solution. I have not decided yet. Will put links. – rism Sep 11 '13 at 13:21
  • http://adamhouldsworth.blogspot.co.uk/2010/02/winforms-visual-inheritance-limitations.html This is the solution I've used in the past. It appears as though the other solution is for abstract base forms, not generic forms. – Adam Houldsworth Sep 11 '13 at 13:22
  • Yes but from what Ive read it seems to be similar principles that can be easily adapted. Im sure there are caveats but Im just trying to get around a generic base class that accepts a typed view model. It should be easy enough to adapt this method to swap in a non generic base to allow me to use the designer. Thanks for your link. – rism Sep 11 '13 at 13:28
  • If you solve your problem, you could always answer your own question - that still adds value to SO. – Adam Houldsworth Sep 11 '13 at 13:28
  • -1: unverified claim. `TypeDescriptionProvider` is not proved to work with generics. You could have asked if the proposed solution really existed and that would have been a perfectly licit question. – ceztko Sep 25 '14 at 20:38

2 Answers2

0

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?

Matt Craig
  • 158
  • 6
  • 1
    I gave up and I don't believe it anymore: `TypeDescriptionProvider` working for generics is just a urban legend wandering in old 404 forum posts or attachment. – ceztko Sep 25 '14 at 20:35
0

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.

nawfal
  • 70,104
  • 56
  • 326
  • 368