38

我为 WinForm UserControl 创建了一个通用基类:

public partial class BaseUserControl<T> : UserControl
{
    public virtual void MyMethod<T>() 
    { 
        // some base stuff here 
    }
}

以及基于此的 UserControl:

public partial class MyControl : BaseUserControl<SomeClass>
{
    public override void MyMethod<SomeClass>() 
    { 
        // some specific stuff here 
        base.MyMethod<SomeClass>();
    }
}

它工作正常,但无法在 VisualStudio 设计器中编辑 MyControl,因为它说它无法加载基类。我试图定义另一个类 BaseUserControl,非泛型,希望它能加载它,但这个技巧似乎不起作用。

我已经有一个解决方法:定义一个接口 IMyInterface<T>,然后将我的控件创建为

public partial class MyControl : UserControl, IMyInterface<SomeClass>

但是我失去了我的基本虚拟方法(没什么大不了的,但仍然......)。

有没有办法为 UserControl 创建一个基本的泛型类,并可以在 VisualStudio 设计器中对其进行编辑?

4

3 回答 3

35

我们正在做同样的事情,我们通过首先专门化一个类并从专门化类派生来解决问题。使用您示例中的代码,这意味着:

public partial class UserControl : UserControlDesignable 
{

...
}
public class UserControlDesignable : BaseUserControl<Someclass> { }

设计师有时仍然表现得有些古怪——但大多数时候它是有效的。

于 2009-03-24T14:25:00.647 回答
14

您必须通过添加一个从您的通用基本形式继承的“常规”类来欺骗设计者。然后,您的可设计表单应该从此类继承。因此,以下 2 个类定义在同一个文件中。您必须确保从通用基本用户控件继承的类是文件中的最后一个类。

public MyForm : EditableCustomerForm
{}

public EditableCustomerForm : GenericForm<Customer>
{}

设计器将在它遇到的代码文件中显示第一个类。

于 2009-03-24T14:27:58.813 回答
3

好吧,这似乎是 Visual Studio 中的一个错误。

通过深入研究框架(实际上是通过添加一个RootDesignerSerializer派生自该方法的自定义类型CodeDomSerializer并覆盖该serialize方法),我能够证明 VS Code Dom 提供程序实际上解析了错误的泛型类,而不是将其视为泛型类它正在将其视为具有 name 的常规类class<T>Type.GetType()当然找不到。

我仍在寻找一种解决方法,但同时可以使用上述解决方案。

有一个 Microsoft.Connect 错误报告,请在https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-上投票通用形式

于 2013-08-13T19:38:53.500 回答