通用的WinForm UserControl基类

39

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

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

基于该控件的用户控件:

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设计器中编辑它?


你不必失去基本的虚拟方法,而是包含实现类而不是继承它。 - Robocide
VS 2015.1 开始,Windows Forms Designer 可以正常显示具有泛型基类的类。请参见示例 - Reza Aghaei
3个回答

36

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

public partial class UserControl : UserControlDesignable 
{

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

设计师有时仍然表现不稳定 - 但大部分时间它正常工作。


虽然这是一个解决方法,但请注意这必须在额外的文件中进行,如果基类是抽象的,并且使用自定义类型提供程序属性(正如在本站的其他帖子中提到的那样),则必须将其放在每个类上。 - yoel halb
仍然是唯一在VS2015中可用的解决方案。微软没有添加本地支持... :-( - Tobias Knauss
@TobiasKnauss 从 VS 2015.1 开始,Windows Forms Designer 可以无障碍地显示具有泛型基类的类。请参见示例 - Reza Aghaei

14

你需要通过添加一个从你的通用基础表单继承的"普通"类来欺骗设计师。 然后,你的可设计表单应该继承自这个类。 因此,在同一个文件中有以下两个类定义。 你必须确保从通用基础用户控件继承的类是文件中最后一个类。

public MyForm : EditableCustomerForm
{}

public EditableCustomerForm : GenericForm<Customer>
{}

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


很好的想法,但请注意,由于设计师在使用之前必须先编译基类,这意味着对 EditableCustomerForm 类进行任何更改都需要重新构建以使设计师生效,而且设计师可能只能在 MyForm 类上工作。 - yoel halb

3

看起来这是Visual Studio的一个错误。

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

我仍在寻找解决此问题的方法,但同时可以使用以上解决方案。

关于此问题的Microsoft.Connect错误报告,请在https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form上投票。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接