【问题标题】:Generic forms and VS designer通用表单和 VS 设计器
【发布时间】:2012-04-18 08:05:27
【问题描述】:

我有一个基类

internal partial class View<T> : UserControl
  where T : class
{
    protected T t;
}

我想从 View 派生一个孩子

internal partial class ViewChild<T> : View<T>
  where T : class
{
}

它工作正常,但我无法在 VS 设计器中编辑 ViewChild。我知道问题是通用基类。但是,我不明白在这种情况下如何避免这种情况。 有什么办法可以解决吗?

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

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

    http://wonkitect.wordpress.com/2008/06/20/using-visual-studio-whidbey-to-design-abstract-forms/

    我真的不建议使用条件编译。使用框架要好得多,而不是反对它。

    基本上,你可以通过现有的框架给VS一个不同的类。你用 TypeDescriptionProvider 属性装饰你的基类,它告诉 VS 使用不同的类作为设计器。

    如原始博客文章中所述,可能存在与此解决方法相关的警告,但我在一个具有 > 25 个从公共基类继承的 UserControls 的项目中很好地工作。

    【讨论】:

    • 这是一个不错的解决方案,但它没有提到泛型。您对它的使用是否涵盖了泛型?
    • 问题域实际上是相同的,即VS托管设计类型的实例。 VS 抱怨泛型的原因是它不能实例化它们,就像抽象类一样。在这方面,所有的泛型都是伪抽象的;如果没有类型参数,它们对运行时毫无意义。为了回答您的问题,我确实简要地使用了通用基类来实现强类型视图(在 Winforms 中)的未完成实现,但截至目前,我已经放弃了这种特定的架构转移,转而支持实现真正的功能。我可能会在月底回到它。
    • +1 如果这个周末有时间,我会尝试用它更新我的旧代码,看看它是否能让我设计基类 - 很好的发现。
    • 我无法让它适用于两个抽象类:-(你有任何代码的链接以及解决方案的演示吗?
    • 谢谢 ;-p 我会说,当 VS2010 被要求做这些事情时,我发现它有点紧张,而且它的行为是不可预测的。在实施此操作时,我不得不重新启动它几次。当我安装一些扩展时它有所帮助。一般来说,实际上,我发现 VS 中的扩展很痛苦,而且没有必要,所以这没什么大不了的。另一件需要注意的事情是,如果您从第三方用户控件(我在看您,WinForms 的 ComponentOne)继承,事情会在性能方面变得棘手。尽管如此,最终还是让它工作了,这意味着我不需要到处都使用#if 块。
    【解决方案2】:

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

    http://adamhouldsworth.blogspot.co.uk/2010/02/winforms-visual-inheritance-limitations.html

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

    • BaseControl&lt;T&gt; : UserControl
    • CustomerControl_Design : BaseControl&lt;Customer&gt;
    • CustomerControl : CustomerControl_Design

    然后,您可以根据DEBUGRELEASE 编译器开关有条件地将此类从代码中切换出来:

    #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
        {
        }
    

    这将让您打开CustomerControl 的派生类,不幸的是您将永远能够在签名中设计带有泛型的 UI 控件。我的解决方案只是启用派生项的设计。

    我不知道为什么 CustomerControl : BaseControl&lt;Customer&gt; 不起作用,因为在这种情况下定义了类型 T,但它根本不起作用 - 我猜是因为通用使用规则。

    为了他们的辩护,微软确实表示不支持。

    【讨论】:

    • 据我了解,这仅适用于具体的客户类型,如果我想使用不同类型的 ViewChild,它将不起作用。我在 View 中有一些基本代码,当我用一些额外的代码扩展 ViewChild 并使用 View、ViewChild、ViewChild
    • @wince 你是对的。正如我在答案中所说,它只解决了派生形式的问题。如果您有一个实际包含内容的通用基本表单,我建议您将这个想法合并,并在 shell 表单中执行类似组合的操作。在我的使用中,基本控件只提供逻辑,而不是视觉效果。
    • @wince 你的View&lt;T&gt;ViewChild&lt;T&gt; 是否也有任何视觉元素或者只是代码?
    • View 只有代码,ViewChild 是一个向导表单,有一些按钮(返回、下一步、取消),我需要许多不同 T 的 ViewChild 对象(演示者)跨度>
    • 我找到了解决方案。不好,但它有效。对于设计时间,我只使用内部类 ViewChild :UserControl
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多