简体   繁体   English

使用自定义 TypeDescriptionProvider 仍然是在 VS2012 设计器中使用通用表单的唯一方法吗?

[英]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.我在网上搜索并在 SO 上找到了一些问题,还有一些博客文章说要使用自定义 TypeDescriptionProvider。 The articles im finding are circa 2008-2010.我发现的文章大约是 2008-2010 年。

Using Visual Studio Whidbey to Design Abstract Forms 使用 Visual Studio Whidbey 设计抽象表单

Generic forms and VS designer 通用表单和 VS 设计器

Is this still the way to go using VS2012, .NET 4.0 in Sept 2013?这仍然是 2013 年 9 月使用 VS2012、.NET 4.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.许多人声称使用 TypeDescriptionProvider 的相同机制适用于抽象基类应该适用于泛型,但是我还没有遇到任何真正让它工作的人。

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).我花了几个小时试图让基于 TypeDescriptionProvider 的解决方案适用于通用基类,但是与抽象基类不同,设计者似乎没有尝试使用指定的类型描述符提供程序(通过使用一个 VS 实例进行调试来验证)另一个 VS 实例的设计器)。

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.甚至 OP 参考文章的作者(似乎是从这里逐字复制的)在评论中也承认他没有对其进行泛型测试。

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.已针对 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.问题是解决方案(阅读演示项目)必须在 VS 进程的生命周期内构建一次。 Every time you start VS, you need to build once, that's all.每次启动VS,都需要构建一次,仅此而已。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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