2009-12-03 16 views
23

Estoy usando WPF con el patrón Model-View-ViewModel. Por lo tanto, mi código detrás de los archivos (.xaml.cs) están todos vacíos, a excepción del constructor con una llamada a InitializeComponent. Por lo tanto, para cada archivo .xaml tengo un archivo coincidente, inútil, .xaml.cs.XAML sin el código .xaml.cs detrás de los archivos

Juro que leí en alguna parte que si el código detrás del archivo está vacío, excepto el constructor, hay una manera de eliminar el archivo del proyecto por completo. Después de buscar en la red, parece que la forma adecuada de hacerlo es utilizar la 'x: Subclase' atributo:

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit" 
    x:Class="MyNamespace.MyClass" 
    x:Subclass="UserControl" 
    d:DesignWidth="700" d:DesignHeight="500"> 

Esto hace lo siguiente en el archivo generado .g.cs:

  1. Elimina el modificador de clase 'parcial' en MyClass.
  2. Agrega la clase 'UserControl' a su lista de subclase.

Parece perfecto. De hecho, si todavía tiene el archivo .xaml.cs en la compilación, ya no compila debido al parcial faltante, así que estoy pensando que esto debe ser correcto. Sin embargo, si elimino el archivo superfluo de la compilación y ejecución, el control no se inicializa correctamente (está en blanco). Esto es, supongo, porque InitializeComponent() no se está llamando. Veo que InitializeComponent no es virtual, por lo que parece que no habría forma de que la clase base lo llamara (a falta de usar la reflexión).

¿Echo de menos algo?

Gracias!

Eric

Respuesta

13

Si sigue Josh Smith's MVVM article, se utiliza para DataTemplates Vistas en lugar de los controles de usuario. Si coloca sus DataTemplates en ResourceDictionaries, no tienen código subyacente. Si no está utilizando el código subyacente de su control de usuario, ¿no significa que podría utilizar un enfoque de DataTemplate?Si lo hace, WPF se encargará de vincular su Vista a su ViewModel por usted.

+0

Gracias Scott. Este es definitivamente un mejor enfoque. – Eric

+0

+1 También lo uso de esta manera. Funciona tan bien que es casi como magia. –

+1

Nota: está disponible en WPF, pero no en Silverlight. – MrSharps

2

que tuvo una discusión con un miembro del equipo de cliente de Windows en el PDC sobre esto, y en este momento, se le dijo que no hay manera más apoyo oficial para eliminar por completo el código detrás de archivo. Como puede ver, puede hacer que compile, pero InitializeComponent() nunca se llama, por lo que el control no se configura correctamente.

El uso de x:Subclass attribute "está destinado principalmente a los idiomas que no admiten declaraciones de clase parciales". No fue pensado para permitir este comportamiento (desafortunadamente).

31

Como otra opción, si usted no quiere ir todo el camino a la utilización de DataTemplates, aquí es un enfoque alternativo para UserControls:

Uso de la x: Código de atributos para incrustar la llamada al constructor en el XAML:

<x:Code><![CDATA[ public MyClass() { InitializeComponent(); }]]></x:Code> 

Eric

+2

Esa es una solución muy resbaladiza. –

+0

dulce. ¿Quién hubiera pensado en eso? –

+3

así ... Me upvote esto, ya que es muy inteligente, pero hay algo que simplemente no se siente bien acerca de tener este tipo de código CDATA en sus archivos XAML ... Al igual que otra persona le preguntó en un tema similar, ¿por qué tenemos ¿Quieres pasar por la molestia de eliminar los archivos vacíos de código subyacente? no les molesta, uno apenas puede verlos sentados allí. Aún así, me gusta tu creatividad :-) –

0

Por pura curiosidad, ¿ha intentado usar esto:

x:Subclass="Control" 

De forma predeterminada, los UserControls requieren la llamada InitializeComponent(), pero los controles estándar de facto no. Me interesaría ver si esto funciona.

-Doug

+0

Acabo de probar esto. No cambió el comportamiento. Sin la llamada a InitializeComponent(), el control está en blanco. – Eric

Cuestiones relacionadas