Visual Studio 设计器中的抽象通用 UserControl 继承

Abstract generic UserControl inheritance in Visual Studio designer

在我的一个项目中,我使用了一个抽象的 UserControl。为了能够在 Visual Studio 中设计此控件,我使用了 this answer 中建议的代码。现在我想将它与另一个通用的抽象 UserControl 一起使用。但如果我这样做

[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<MyBaseControl<T>, UserControl>))]

我收到编译器错误

CS0416: an attribute argument cannot use type parameters

删除类型参数显然也无法编译。

我无法从非泛型基础派生 MyBaseControl class,因为它已经派生自泛型基础 class,所以我尝试用接口装饰它并像这样使用它:

[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<IMyBaseControl, UserControl>))]

这个 可以 编译,但是当我打开设计视图时,我的控件没有被渲染,而是出现错误

The number of generic arguments provided doesn't equal the arity of the generic type definition.

有办法解决吗?

我想你有一个控件 AbstractGenericBase<T> : GenericBase<T> 其中 GenericBase<T> 是一个具有这样定义的控件:GenericBase<T>: UserControl.

所以如果你想在设计器中显示AbstractGenericBase<T>,你可以使用这个代码:

using System.ComponentModel;
using System.Windows.Forms;

#if DEBUG
public abstract partial class AbstractGenericBase<T> : NonGenericBase
#else
public partial class AbstractGenericBase<T> : GenericBase<T>
#endif
{
    public AbstractGenericBase()
    {
        InitializeComponent();
    }
}
#if DEBUG
public class NonGenericBase : GenericBase<object> { }
#endif

备注

  • 目标是在设计器中显示此 class:
    public abstract partial class AbstractGenericBase<T> : GenericBase<T>
  • 如果 T 有一些类型约束,而不是 GenericBase<object> 中的 object,请使用满足通用约束的 Dummy
  • 解决方案基于以下事实:当设计人员想要在设计界面中显示您的控件时,它会尝试创建您的控件的基础 class 实例。当您的控件的基础 class 是通用的 class 时,设计者不知道如何创建基础 class.
    的实例 在上面的解决方案中,为了设计时支持,我们告诉设计者我们控件的基数是 NonGenericBase,但是对于 运行 时间,我们将 GenericBase<T> 作为基数 class我们的控制。