C# 通用窗体和VS设计器

C# 通用窗体和VS设计器,c#,winforms,C#,Winforms,我有一个基础班 internal partial class View<T> : UserControl where T : class { protected T t; } 内部部分类视图:UserControl T:在哪里上课 { 保护T; } 我想从视图中导出一个孩子 internal partial class ViewChild<T> : View<T> where T : class { } 内部部分类视图子类:视图 T:在哪

我有一个基础班

internal partial class View<T> : UserControl
  where T : class
{
    protected T t;
}
内部部分类视图:UserControl
T:在哪里上课
{
保护T;
}
我想从视图中导出一个孩子

internal partial class ViewChild<T> : View<T>
  where T : class
{
}
内部部分类视图子类:视图
T:在哪里上课
{
}
它工作正常,但我无法在VS设计器中编辑ViewChild。我知道问题是泛型基类。然而,我不明白在这种情况下如何避免这种情况。
有没有办法解决这个问题?

泛型会破坏设计器,因为它无法在没有类型
T
的情况下实例化类。我在我的博客文章中解释了一个解决方法:

简而言之,您需要使用中间类“解析”类型:

  • BaseControl:UserControl
  • CustomerControl\u设计:BaseControl
  • CustomerControl:CustomerControl\u设计
然后,您可以根据
DEBUG
RELEASE
编译器开关有条件地将此类从代码中切换出来:

#if DEBUG

namespace MyNamespace
{
    using System;


    public partial class CustomerEditorControl_Design : BaseEditorControl<Customer>
    {
        public CustomerEditorControl_Design()
            : base()
        {
            InitializeComponent();
        }
    }
}

#endif

    public partial class CustomerEditorControl
#if DEBUG
        : CustomerEditorControl_Design
#else
        : BaseEditorControl<Customer>
#endif
    {
    }
#如果调试
名称空间MyNamespace
{
使用制度;
公共部分类CustomerEditorControl\u设计:BaseEditorControl
{
公共客户编辑或控制_设计()
:base()
{
初始化组件();
}
}
}
#恩迪夫
公共部分类CustomerEditorControl
#如果调试
:客户编辑或控制\u设计
#否则
:BaseEditorControl
#恩迪夫
{
}
这将允许您打开
CustomerControl
的派生类,不幸的是,永远无法设计签名中带有泛型的UI控件。我的解决方案只支持派生项的设计

我不知道为什么
CustomerControl:BaseControl
不能工作,因为在本例中定义了类型
t
,但它根本不能工作-我猜是因为一般用法的规则


微软为他们辩护说,这不受支持。

还有另一种方法,它不依赖于编译器标志:

我真的不建议使用条件编译。更好的方法是使用框架,而不是反对它

基本上,您可以通过现有框架为VS提供不同的类。您使用TypeDescriptionProvider属性装饰基类,该属性告诉VS使用不同的类作为设计器


正如在最初的博客文章中提到的,可能有一些与此解决方案相关的警告,但我在一个项目中使用了它,该项目继承自一个公共基类的用户控件超过25个。

据我所知,这只适用于具体的客户类型,如果我想将ViewChild用于不同的类型,它将不起作用。当我用一些额外的代码扩展ViewChild并使用View、ViewChild、ViewChild时,我在视图中有一些基本代码etc@wince你说得对。正如我在回答中所说,它只解决了派生形式的问题。如果你有一个通用的基本表单,它实际上包含了内容,我建议你把这个想法组合起来,做一些类似于shell表单中的合成的事情。在我的使用中,基本控件只提供逻辑,而不提供视觉。@wince您的
视图
ViewChild
是否也有任何视觉元素,或者只是代码?视图只有代码,ViewChild是一个向导表单,有一些按钮(后退、下一步、取消),我需要许多具有不同T(演示者)的ViewChild对象我找到了解决办法。不太好,但很管用。在设计时,我只使用内部类ViewChild:usercontrol这是一个很好的解决方案,但它没有提到泛型。您的使用是否涵盖泛型?问题域实际上是相同的,即与托管设计类型的实例相比。VS抱怨泛型的原因是它不能像抽象类那样实例化它们。在这方面,所有泛型都是伪抽象的;如果没有类型参数,它们对运行时没有意义。为了回答您的问题,我曾简要地将泛型基类用于强类型视图的未完成实现(在Winforms中),但到目前为止,我已经放弃了这种特定的架构转移,转而支持实现真正的功能。我可能会在月底再讨论它。+1如果这个周末有时间,我会尝试用它更新我的旧代码,看看它是否能让我设计基类-很好的发现。我无法让它在两个抽象类中工作:-(您是否有任何与解决方案演示相关的代码的链接?谢谢;-p我会说,当要求VS2010执行这些操作时,我觉得VS2010有点不稳定,其行为是不可预测的。在实现此功能时,我不得不重新启动它几次。当我安装一些扩展时,它很有帮助。通常,实际上,我在VS中找到了扩展这很痛苦,也不必要,所以没什么大不了的。另一个需要注意的是,如果你从第三方用户控件继承(我在看你,WinForms的ComponentOne),那么从性能角度看,事情会变得很棘手。不过,最终还是成功了,这意味着我不需要到处都是if块。