2009-08-24 10 views
6

Ich möchte ein wiederverwendbares WPF-Fenster passend für verschiedene Typen T. machen Ich habe einen Designer und eine Codebehind-Datei.WPF Generic Windows

kann ich so etwas tun?

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

Antwort

3

Leider, was Sie wollen, ist nicht ganz möglich.

Aktualisierung: Vor .NET 4.0 (d. H. Wenn diese Antwort ursprünglich geschrieben wurde), XAML support for consuming generic types was very limited; z.B. Generika haben nur am Root-Element gearbeitet. In .NET 4.0 wurden einige Einschränkungen aufgehoben.

In .NET 4.0 können Sie einen vollständig spezialisierten generischen Typ erstellen. Während also XAML selbst noch kein Konzept von generischen Typen hat, kann es auf Spezialisierungen von generischen Typen verweisen. (Analog kann XAML nicht den Begriff List<> ausdrücken, aber es kann den Begriff List<int> ausdrücken). Ausführliche Informationen finden Sie unter MSDN page "Generics in XAML".

Sie können Instanzen von spezialisierten generischen Typen mit der x:TypeArguments Directive erstellen. Zum Beispiel mit x zu XAML Namensraum gebunden, sys zum System Namespace und scg-System.Collections.Generic und Ihre eigenen MyWindows' Namespace my dann gebunden:

  • <my:MyWindows x:TypeArguments="x:String"> würde eine MyWindows<string> Instanz konstruieren.
  • <scg:List x:TypeArguments="sys:Tuple(sys:String,sys:Int32)"> wäre ein List<Tuple<string,int>>

Verwendung generische Typen konstruieren daher nicht mehr ein Problem in XAML!

Ach, möchten Sie definieren einen generischen Typ in XAML. Das ist nicht möglich. Es gibt zwei Problemumgehungen hier. Erstens (und basierend auf Ihren Kommentaren zu einer anderen Frage, ich denke, das ist was Sie wollen) können Sie einen Typ einfach als einfachen Parameter übergeben. Wenn Sie dies tun, verlieren Sie alle Kompilierungszeit Sicherheitsfunktionen, die Generika bieten, aber oft genug sind diese nicht relevant. Zweitens können Sie eine normale nicht-generische Klasse mit Codebehind in XAML definieren und einfach eine generische Basisklasse für die Wiederverwendung von Code verwenden. Auf diese Weise erhalten Sie zumindest einige richtige Generikasicherheit und Wiederverwendung.

+3

Sie sind falsch, wenn Sie sagen "XAML zum Beispiel unterstützen Generika gar nicht" es tut über x: TypeArguments, siehe http://blogs.windowsclient.net/rob_relyea/archive/2009/06/01/xaml-using-generic-types-in-xaml-2009.aspx – Grokodile

+0

... und nach dem Aussehen davon hat sich das geändert! http://msdn.microsoft.com/en-us/library/ee956431%28v=vs.110%29.aspx Ich werde die Antwort aktualisieren :-). –

+0

@EamonNerbonne Sorry mein Schlechter, ich habe gerade über die generische XAML-Einschränkung erfahren. :) Ich habe dieses Problem gestern kennengelernt, als ich mein eigenes Containersteuerelement aufrollte, das ein generisches Argument für das zu aggregierende untergeordnete Steuerelement benötigte - ich konnte das Containersteuerelement in XAML nicht definieren. Im Wesentlichen fragt Nuno hier http: //social.msdn.microsoft.com/Forums/vstudio/en-US/02ca0499-80af-4c56-bb80-f1185a619a9e/creating-generic-wpf-user-control Am Ende schrieb ich meinen generischen Container ohne XAML (glückliche Kontrolle ist einfach) aber das aggregierte Kontrolle ist immer noch XAML :) – MickyD

6

Schamlos von here kopiert (und somit nicht getestet)

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

und 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

Dies funktioniert absolut auf VS 2010 SP1 und IMO ist die richtige Antwort auf die Frage! 'xmlns: src' Direktive ist grundlegend, damit Visual Studio den Namespace sehen kann. Cool! – ceztko