2009-03-24 11 views
33

he creado una clase genérica de base para un WinForm control de usuario:clase base genérica para WinForm control de usuario

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

Y un control de usuario sobre la base de que:

public partial class MyControl : BaseUserControl<SomeClass> 
{ 
    public override void MyMethod<SomeClass>() 
    { 
     // some specific stuff here 
     base.MyMethod<SomeClass>(); 
    } 
} 

Funciona bien, pero MyControl no se puede editar en el diseñador de VisualStudio, porque dice que no puede cargar la clase base. Intenté definir otra clase BaseUserControl, no genérica, con la esperanza de que la cargara, pero el truco no parece funcionar.

Ya tengo una solución: definir una interfaz, IMyInterface <T>, y luego crear mi control como

public partial class MyControl : UserControl, IMyInterface<SomeClass> 

Pero pierdo mis métodos base virtual (no es un gran problema, pero aún así ...)

¿Existe alguna manera de crear una clase genérica básica para un UserControl, con la posibilidad de editarla en el Diseñador de VisualStudio?

+0

usted no tiene que perder sus métodos virtuales de base, contienen la clase Implementor en lugar de heredar de ella. – Robocide

Respuesta

34

Estamos haciendo lo mismo y trabajamos por la especialización de una clase y derivamos de la clase especializada. Utilizando el código de su ejemplo, esto significa algo así como:

public partial class UserControl : UserControlDesignable 
{ 

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

El diseñador sigue actuando escamosa a veces - pero la mayoría de las veces funciona.

+0

Si bien hay una solución alternativa, tenga en cuenta que esto se debe hacer en un archivo adicional, y si la base es abstracta y se usa un atributo de proveedor de tipo personalizado (como se menciona en otras publicaciones en este sitio) tendrá que ir a cada clase –

+0

sigue siendo la única solución de trabajo en VS2015. No se agregó compatibilidad nativa con MS ...:-( –

14

Tendrás que engañar al diseñador agregando una clase 'normal' que hereda de tu formulario base genérico. Su forma elegible debe heredar de esta clase. Las siguientes 2 definiciones de clase están, por lo tanto, en el mismo archivo. Deberá asegurarse de que la clase que hereda del control de usuario base genérico sea la última clase del archivo.

public MyForm : EditableCustomerForm 
{} 

public EditableCustomerForm : GenericForm<Customer> 
{} 

El diseñador mostrará la primera clase en el archivo de código que encuentre.

+0

Excelente idea, pero tenga en cuenta que dado que una clase base ya debe compilarse antes de que el diseñador pueda usarla, significa que para cualquier cambio en la clase EditableCustomerForm tendrá que ser reconstruida para que el diseñador tome efecto, también el diseñador probablemente solo trabaje en la clase MyForm –

3

Bueno, esto parece ser un error en Visual Studio.

Por la excavación en el marco (en realidad mediante la adición de un RootDesignerSerializer con un tipo personalizado derivado de CodeDomSerializer y reemplazando el método serialize), que fue capaz de demostrar que el proveedor Código VS Dom está parseando mal las clases genéricas, y en su lugar de considerarlo como una clase genérica lo está considerando como una clase regular con el nombre class<T>, que Type.GetType() por supuesto no puede encontrar.

Todavía estoy buscando una manera de evitarlo, pero mientras tanto uno puede usar las soluciones anteriores.

Hay un informe de error Microsoft.Connect en él, por favor voten en él en https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form

Cuestiones relacionadas