我想定义以下控件:
public partial class ObjectSelectorControl<T> : UserControl where T : class
问题是设计师无法解决这个问题。这个问题有解决方法吗?
这有效
public class Control1<T> : UserControl { ... }
public class Control2 : Control1<double> { ... }
public class Control3 : Control2 { ... }
在这里读过:
听起来很像我们在项目中所做的。
有一个通用的基类:
public partial class controlItemList<TBaseItem, TBaseItemCollection> : UserControl, IUIDispatcher
where TBaseItem : new()
where TBaseItemCollection : IItemCollection<TBaseItem>
然后,对于每次使用,我们定义一个非泛型版本(设计者仍然无法使用):
public class controlMessagesNonGenericParent : controlItemList<MailItem, MailItemCollection>
{
}
...然后我们派生出可以在设计师中使用的控件:
public partial class controlMessages : controlMessagesNonGenericParent
{
...
}
对于能够使用设计器,您的控件可以或不可以执行的操作有一些限制。从根本上说,它们都围绕着能够实例化你的类的设计者(必须有一个无参数的构造函数,不能是abstract
等)。因为设计者不知道作为泛型参数传递什么类型(我怀疑这甚至是一个考虑因素),所以你的类无法实例化。
你最好的希望是创建你的UserControl
并将构造函数更改为protected
(我相信,这将起作用,因为设计师使用反射并忽略了可见性,但我并非100%正面)。然后,您可以继承该UserControl
并创建您的泛型类并调用基础(protected
)构造函数。
我不相信这是可能的,因为设计师会调用你班级的一个实例。如果你使用泛型,设计师不知道传入'T'的类型。
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105876
该错误已发布到微软的网站,你可以看到它标记为“推迟”目前没有解决方案! 。
使用组合而不是泛型。而不是使用ObjectSelectorControl,给出另一种类型的通用成员(可能是Selector<T>
)并对该对象采取行动,而不是试图强迫自己成为通用的。
我不知道在哪一点(使用哪个C#/ .NET / VS版本更新),但现在可以像创建任何其他泛型类一样创建泛型控件。
如果以标准方式在VS中创建UserControl
(即通过GUI添加它),只需在类声明的两个部分(“基础”类代码和设计器管理文件)中添加<T>
。实际上,这就是你引用的代码中的内容。