2009-12-03 10 views
23

J'utilise WPF avec le modèle Model-View-ViewModel. Ainsi, mon code derrière les fichiers (.xaml.cs) sont tous vides, à l'exception du constructeur avec un appel à InitializeComponent. Ainsi, pour chaque fichier .xaml, j'ai un fichier .xaml.cs inutile et inutile.XAML sans le code .xaml.cs derrière les fichiers

Je jure que j'ai lu quelque part que si le code derrière le fichier est vide, sauf pour le constructeur, il existe un moyen de supprimer le fichier du projet tout à fait. Après recherche sur le net, il semble que la manière appropriée de le faire est d'utiliser le « x: Sous » attribut:

<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"> 

Cela effectue les opérations suivantes dans le fichier généré .g.cs:

  1. Supprime le modificateur de classe "partial" sur MyClass.
  2. Ajoute la classe 'UserControl' à sa liste de sous-classes.

Semble parfait. En effet, si vous avez toujours le fichier .xaml.cs dans la construction, il ne compile plus à cause du partiel manquant - donc je pense que cela doit être correct. Toutefois, si je supprime le fichier superflue de la génération et de l'exécution, le contrôle n'est pas initialisé correctement (il est vide). C'est, je présume, parce que InitializeComponent() n'est pas appelé. Je vois que InitializeComponent n'est pas virtuel, il semble donc qu'il n'y aurait aucun moyen pour la classe de base de l'appeler (à moins d'utiliser la réflexion).

Ai-je raté quelque chose?

Merci!

Eric

Répondre

13

Si vous suivez Josh Smith's MVVM article, il utilise DataTemplates pour les vues plutôt que les contrôles utilisateur. Si vous placez vos DataTemplates dans ResourceDictionaries, ils n'ont pas de code-behind du tout. Si vous n'utilisez pas le code-behind de votre contrôle utilisateur, cela ne signifie-t-il pas que vous pourriez utiliser une approche DataTemplate?Si vous faites cela, WPF se chargera de lier votre vue à votre ViewModel pour vous.

+0

Merci Scott. C'est certainement une meilleure approche. – Eric

+0

+1 J'utilise aussi cette façon. Ça marche tellement bien que c'est presque magique. –

+1

Remarque: est disponible dans WPF, mais pas Silverlight. – MrSharps

2

J'ai eu une discussion avec un membre de l'équipe Windows Client au PDC à ce sujet, et en ce moment, a dit qu'il n'y a pas de moyen officiellement prise en charge d'éliminer complètement le code derrière le fichier. Comme vous pouvez le voir, vous pouvez l'obtenir pour compiler, mais InitializeComponent() n'est jamais appelé, donc le contrôle n'est pas configuré correctement.

L'utilisation de x:Subclass attribute "est principalement destinée aux langages qui ne supportent pas les déclarations de classes partielles." Il n'était pas prévu d'autoriser ce comportement (malheureusement).

31

Comme une autre option, si vous ne voulez pas aller tout le chemin à l'aide DataTemplates, voici une autre approche pour UserControls:

Utilisez le x: attributs de code pour intégrer l'appel du constructeur dans le XAML:

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

Eric

+2

C'est une solution très lisse. –

+0

doux. qui aurait pensé à ça? –

+3

bien ... Je l'ai surpassé, car c'est très intelligent, mais il y a quelque chose qui ne me semble pas correct d'avoir ce genre de code CDATA dans vos fichiers XAML ... Comme quelqu'un d'autre l'a demandé dans un sujet similaire, pourquoi avons-nous voulez-vous passer la peine de supprimer les fichiers code-behind vides du tout? ils ne dérangent pas, on peut difficilement les voir assis là. Pourtant, j'aime votre créativité :-) –

0

par pure curiosité, vous avez essayé d'utiliser ceci:

x:Subclass="Control" 

Par défaut, UserControls requiert l'appel InitializeComponent(), mais pas les contrôles standard. Je serais intéressé de voir si cela fonctionne.

-Doug

+0

Juste essayé ceci. Cela n'a pas changé le comportement. Sans l'appel à InitializeComponent(), le contrôle est vide. – Eric