2009-03-24 15 views
33

ho creato una classe generica di base per una WinForm UserControl:classe di base generico per WinForm UserControl

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

E un controllo utente sulla base di tale:

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

Funziona bene, ma MyControl non può essere modificato in VisualStudio Designer, perché dice che non può caricare la classe base. Ho provato a definire un'altra classe BaseUserControl, non generico, sperando che lo caricasse, ma il trucco non sembra funzionare.

Ho già una soluzione alternativa: definire un'interfaccia, IMyInterface <T>, e quindi creare il mio controllo, come

public partial class MyControl : UserControl, IMyInterface<SomeClass> 

Ma perdo i miei metodi base virtuali (non un grande affare, ma ancora ...).

C'è un modo per creare una classe generica di base per un UserControl, con la possibilità di modificarlo in VisualStudio Designer?

+0

non dovete perdere i metodi virtuali di base, contengono la classe alle implementazioni invece di ereditare da essa. – Robocide

risposta

34

Stiamo facendo la stessa cosa e lavoriamo specializzando prima una classe e derivando dalla classe specializzata. Utilizzando il codice dal vostro esempio questo significa qualcosa come:

public partial class UserControl : UserControlDesignable 
{ 

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

Il progettista è ancora in qualità traballante a volte - ma la maggior parte del tempo funziona.

+0

Mentre una soluzione alternativa, si noti che questo deve in un file aggiuntivo, e se la base è astratta e uno sta usando un attributo provider di tipo personalizzato (come è menzionato in altri post su questo sito) dovrà andare su ogni classe –

+0

ancora l'unica soluzione funzionante in VS2015. Nessun supporto nativo aggiunto da MS ...:-( –

14

Dovrai ingannare il progettista aggiungendo una classe 'normale' che eredita dal tuo modulo di base generico. Il tuo modulo designabile dovrebbe quindi ereditare da questa classe. Le seguenti 2 definizioni di classe sono quindi nello stesso file. Dovrai assicurarti che la classe che eredita dal controllo utente di base generico sia l'ultima classe nel file.

public MyForm : EditableCustomerForm 
{} 

public EditableCustomerForm : GenericForm<Customer> 
{} 

Il progettista visualizzerà la prima classe nel file di codice che incontra.

+0

Ottima idea, ma si noti che dal momento che una classe base deve essere già compilata prima che il progettista possa usarla, significa che per qualsiasi modifica alla classe EditableCustomerForm dovrà essere ricostruita affinché il designer abbia effetto, anche il designer funzionerà probabilmente solo sulla classe MyForm –

3

Bene questo sembra essere un bug in Visual Studio.

Scavando nel quadro (in realtà con l'aggiunta di un RootDesignerSerializer con un tipo personalizzato derivato da CodeDomSerializer e override del metodo serialize), sono stato in grado di dimostrare che il provider VS Codice Dom è in realtà il parsing sbagliato le classi generiche, e invece di considerarlo come una classe generica lo sta considerando come una classe regolare con il nome class<T>, che non può ovviamente trovare Type.GetType().

Sto ancora cercando un modo per aggirare il problema, ma nel frattempo si possono usare le soluzioni di cui sopra.

C'è un bug report Microsoft.Connect su di esso, si prega di votare su di esso a https://connect.microsoft.com/VisualStudio/feedback/details/797279/win-forms-designer-error-when-inheriting-from-a-generic-form

Problemi correlati