2009-08-24 13 views
6

Quiero hacer una ventana WPF reutilizable adecuada para diferentes tipos T. Tengo un diseñador y un archivo de código subyacente.WPF Windows genérico

¿Puedo hacer algo como esto?

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

Respuesta

3

Por desgracia, lo que quiere no es bastante posible.

Actualización: Antes .NET 4.0 (es decir, cuando esta respuesta se escribió originalmente), XAML support for consuming generic types was very limited; p.ej. los genéricos solo funcionaron en el elemento raíz. En .NET 4.0, se eliminaron algunas restricciones.

En .NET 4.0, puede construir un tipo genérico totalmente especializado. Entonces, aunque XAML aún no tiene ningún concepto de tipos genéricos, puede referirse a especializaciones de tipos genéricos. (Por analogía, XAML no puede expresar la noción List<> pero puede expresar la noción List<int>). Para detalles completos, vea el MSDN page "Generics in XAML".

Puede construir instancias de tipos genéricos especializados con el x:TypeArguments Directive. Por ejemplo, con x obligado a espacio de nombres XAML, sys a la System espacio de nombres, y scg a System.Collections.Generic, y espacio de nombres de sus propios MyWindows' obligado a my a continuación:

  • <my:MyWindows x:TypeArguments="x:String"> construiría una instancia MyWindows<string>.
  • <scg:List x:TypeArguments="sys:Tuple(sys:String,sys:Int32)"> construiría un List<Tuple<string,int>>

El uso de tipos genéricos, por tanto, ya no es un problema en XAML!

Desear, quiere definir un tipo genérico en XAML. Eso no es posible. Hay dos soluciones aquí. En primer lugar (y en base a sus comentarios sobre otra pregunta, creo que esto es lo que desea) puede pasar simplemente un tipo como un parámetro simple. Si hace esto, perderá todas las características de seguridad en tiempo de compilación que proporcionan los genéricos, pero a menudo esas no son relevantes. En segundo lugar, puede definir una clase normal no genérica con código subyacente en XAML, y simplemente usar una clase base genérica para la reutilización de código. De esa manera, obtendrá al menos algunos medicamentos genéricos adecuados de seguridad y reutilización.

+3

Usted está equivocado cuando dice "XAML, por ejemplo, no es compatible con los genéricos en absoluto" se hace a través de x: TypeArguments, vea http://blogs.windowsclient.net/rob_relyea/archive/2009/06/01/xaml-using-generic-types-in-xaml-2009.aspx – Grokodile

+0

... y por el aspecto de eso, esto ha cambiado! http://msdn.microsoft.com/en-us/library/ee956431%28v=vs.110%29.aspx Actualizaré la respuesta :-). –

+0

@EamonNerbonne Lo siento mal, acabo de enterarme de la restricción genérica de XAML. :) De hecho, me encontré con este problema ayer cuando estaba rodando mi propio control de contenedor que tomaba un argumento genérico para agregar el control secundario: no pude definir el control de contenedor en XAML. Esencialmente lo que Nuno está preguntando aquí http: //social.msdn.microsoft.com/Forums/vstudio/en-US/02ca0499-80af-4c56-bb80-f1185a619a9e/creating-generic-wpf-user-control Al final escribí mi contenedor genérico sin XAML (el control afortunado es simple) pero el agregado el control sigue siendo XAML :) – MickyD

6

Desvergonzadamente copiado de here (y por lo tanto no probado)

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

y 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

Esto absolutamente funciona en VS 2010 SP1 y la IMO es la respuesta correcta a la pregunta! La directiva 'xmlns: src' es fundamental para permitir que Visual Studio vea el espacio de nombres. ¡Guay! – ceztko