2009-08-24 12 views
6

Desidero creare una finestra WPF riutilizzabile adatta per diversi tipi T. Ho un designer e un file codebehind.Windows generico WPF

posso fare qualcosa di simile?

/* Code behind file */ 
public partial class MyWindows<T> : Window 
{} 

risposta

3

Purtroppo, ciò che si vuole non è del tutto possibile.

Aggiornamento: Prima di .NET 4.0 (ad esempio, quando questa risposta è stata scritta in origine), XAML support for consuming generic types was very limited; per esempio. i generici hanno funzionato solo sull'elemento radice. In .NET 4.0, alcune restrizioni sono state rimosse.

In .NET 4.0, è possibile creare un tipo generico completamente specializzato. Pertanto, anche se lo stesso XAML non ha ancora alcun concetto di tipi generici, lo può fare riferimento alle specializzazioni dei tipi generici. (Per analogia, XAML non può esprimere la nozione List<> ma può esprimere la nozione List<int>). Per i dettagli completi, consultare lo MSDN page "Generics in XAML".

È possibile creare istanze di tipi generici specializzati con x:TypeArguments Directive. Ad esempio, con x destinata a spazio dei nomi di XAML, sys al System spazio dei nomi, e scg-System.Collections.Generic, e namespace le proprie MyWindows' legato a my poi:

  • <my:MyWindows x:TypeArguments="x:String"> sarebbe costruire un'istanza MyWindows<string>.
  • <scg:List x:TypeArguments="sys:Tuple(sys:String,sys:Int32)"> costruirebbe un List<Tuple<string,int>>

Utilizzando i tipi generici è quindi non è più un problema in XAML!

Purtroppo, si vuole definire un tipo generico in XAML. Non e possibile. Ci sono due soluzioni alternative qui. In primo luogo (e in base ai tuoi commenti su un'altra domanda penso che questo sia ciò che desideri) puoi semplicemente passare un tipo come parametro semplice. Se lo fai, perdi tutte le funzionalità di sicurezza in fase di compilazione fornite dai generici, ma spesso quelle non sono rilevanti. In secondo luogo, è possibile definire una normale classe non generica con codebehind in XAML e utilizzare semplicemente una classe base generica per il riutilizzo del codice. In questo modo si ottiene almeno un po 'di sicurezza e riutilizzo adeguati generici.

+3

Si sbaglia quando si dice "XAML, per esempio, non supporta generici a tutti" si fa tramite x: TypeArguments, vedi http://blogs.windowsclient.net/rob_relyea/archive/2009/06/01/xaml-using-generic-types-in-xaml-2009.aspx – Grokodile

+0

... e dall'aspetto di esso, questo è cambiato! http://msdn.microsoft.com/en-us/library/ee956431%28v=vs.110%29.aspx Aggiornerò la risposta :-). –

+0

@EamonNerbonne Scusa il mio male, ho appena saputo della restrizione generica XAML. :) In realtà mi sono imbattuto in questo problema ieri mentre stavo arrotolando il mio controllo contenitore che ha assunto un argomento generico per il controllo figlio da aggregare - Non riuscivo a definire il controllo contenitore in XAML. In sostanza ciò che Nuno sta chiedendo qui http: //social.msdn.microsoft.com/Forums/vstudio/en-US/02ca0499-80af-4c56-bb80-f1185a619a9e/creating-generic-wpf-user-control Alla fine ho scritto il mio contenitore generico senza XAML (il controllo fortunato è semplice) ma l'aggregato il controllo è ancora XAML :) – MickyD

6

spudoratamente copiati da here (e quindi non testato)

public class ViewBase<T> : Window, IView where T : class, IViewModel 
{ 
    public virtual T Model 
    { 
     get { return DataContext as T; } 
     set { DataContext = value; } 
    } 
} 

e XAML

<src:ViewBase 
    x:Class="View" 
    x:TypeArguments="src:IViewModel" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:src="clr-namespace:MyNamespace" 
    Height="480" Width="640"> 
... 
</src:ViewBase> 
+1

Questo funziona assolutamente su VS 2010 SP1 e IMO è la risposta corretta alla domanda! La direttiva 'xmlns: src' è fondamentale per consentire a visual studio di vedere lo spazio dei nomi. Freddo! – ceztko