Универсальный базовый класс для 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?


person Filini    schedule 24.03.2009    source источник
comment
вам не нужно терять базовые виртуальные методы, содержать класс Implementor вместо того, чтобы наследовать от него.   -  person Robocide    schedule 06.09.2010
comment
Начиная с VS 2015.1, Windows Forms Designer без проблем показывает классы, имеющие общий базовый класс. См. пример.   -  person Reza Aghaei    schedule 25.12.2019


Ответы (3)


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

public partial class UserControl : UserControlDesignable 
{

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

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

person bernhardrusch    schedule 24.03.2009
comment
Хотя это обходной путь, обратите внимание, что это должно быть в дополнительном файле, и если база является абстрактной и один использует атрибут поставщика настраиваемого типа (как это упоминается в других сообщениях на этом сайте), он должен будет идти в каждом классе - person yoel halb; 14.08.2013
comment
все еще единственное рабочее решение в VS2015. Нет встроенной поддержки, добавленной MS ... :-( - person Tobias Knauss; 12.02.2018
comment
@TobiasKnauss Начиная с VS 2015.1, Windows Forms Designer без проблем показывает классы, которые имеют общий базовый класс. См. пример. - person Reza Aghaei; 25.12.2019

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

public MyForm : EditableCustomerForm
{}

public EditableCustomerForm : GenericForm<Customer>
{}

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

person Frederik Gheysels    schedule 24.03.2009
comment
Отличная идея, но обратите внимание, что, поскольку базовый класс уже должен быть скомпилирован, прежде чем дизайнер сможет его использовать, это означает, что для любых изменений в классе EditableCustomerForm его нужно будет перестроить, чтобы дизайнер мог повлиять на него, также дизайнер, вероятно, будет работать только в классе MyForm - person yoel halb; 14.08.2013

Кажется, это ошибка в 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

person yoel halb    schedule 13.08.2013