Подтвердить что ты не робот

Общий базовый класс для WinForm UserControl

Я создал общий базовый класс для 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>();
    }
}

Он отлично работает, но MyControl не может быть отредактирован в VisualStudio Designer, потому что он говорит, что он не может загрузить базовый класс. Я попытался определить другой класс BaseUserControl, не общий, надеясь, что он загрузит его, но трюк не работает.

У меня уже есть обходное решение: определите интерфейс, IMyInterface <T> , а затем создайте мое управление как

public partial class MyControl : UserControl, IMyInterface<SomeClass>

Но я теряю базовые виртуальные методы (не большое дело, но все же...).

Есть ли способ создать базовый общий класс для UserControl, с возможностью его редактирования в VisualStudio Designer?

4b9b3361

Ответ 1

Мы делаем то же самое, и мы работаем, специализируясь на классе сначала и выходим из специализированного класса. Используя код из вашего примера, это означает что-то вроде:

public partial class UserControl : UserControlDesignable 
{

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

Дизайнер по-прежнему действует flaky иногда - но большую часть времени он работает.

Ответ 2

Вам придется обмануть конструктора, добавив "обычный" класс, который наследуется от вашей базовой базовой формы. Ваша назначаемая форма должна наследоваться от этого класса. Таким образом, следующие 2 определения классов находятся в одном файле. Вы должны убедиться, что класс, который наследуется от базового пользовательского элемента управления, является последним классом в файле.

public MyForm : EditableCustomerForm
{}

public EditableCustomerForm : GenericForm<Customer>
{}

Дизайнер отобразит первый класс в файле кода, с которым он сталкивается.

Ответ 3

Ну, похоже, это ошибка в Visual Studio.

Перекопав в фреймворк (на самом деле, добавив RootDesignerSerializer с пользовательским типом, полученным из CodeDomSerializer и переопределив метод 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

Ответ 4

Версия Visual Studio >= VS2015.1

Начиная с VS2015.1, Windows Forms Designer показывает классы, которые имеют общий базовый класс без каких-либо проблем. Поэтому обходной путь, который находится в других сообщениях, больше не требуется для более новых версий VS, и следующий класс будет показан в дизайнере без каких-либо проблем:

public class SomeClassControl:GenericControl<SomeClass>
{
}

Старые версии Visual Studio

Для старых версий Visual Studio используйте обходное решение, описанное в других сообщениях:

public class SomeClassControl:SomeClassControlBase
{
}
public class SomeClassControlBase:GenericControl<SomeClass>{}