2009-05-25 5 views
6

J'essaie d'utiliser une approche MVVM-ish pour mon développement WPF. J'ai mes classes de modèle de vue logique sous l'espace de noms ViewModel et j'ai un style correspondant pour ces classes de modèle de vue sous l'espace de noms View. Pour l'instant, j'ai mes informations de vue dans les fichiers XAML ResourceDictionary, en tant que DataTemplates et Styles, qui sont tous fusionnés dans le seul App.Resources ResourceDictionary dans app.xaml.Principes de base de WPF: Styles globaux partagés pour MVVM

Cependant, je suis confronté à une sorte de problème poulet/oeuf. Je veux qu'il y ait des styles globaux que j'utilise partout. Par exemple, je veux mon propre style de texte personnalisé appelé MonkeyText qui pourrait être utilisé dans divers styles partout. Je ne peux pas simplement définir ceci dans le fichier app.xaml, parce que les resourcedictionarys qui voudront utiliser MonkeyText sont inclus par ce fichier app.xaml.

Je suppose que si cela est impossible, une alternative serait d'utiliser UserControls au lieu d'utiliser principalement DataTemplates pour établir mes vues? Je crains que l'utilisation de UserControls ne lie trop étroitement les parties VM et V. Pour cette raison, WPF fournit DynamicResources.

Répondre

10

Les ressources statiques - qui ressemblent le plus à des références «traditionnelles» en programmation - ont juste le problème que vous avez rencontré; ils doivent être définis et chargés avant que le style soit analysé. DynamicResources, d'autre part, n'a pas besoin d'être défini avant le moment où il est utilisé. En effet, vous pouvez même les créer à la volée. WPF s'assure que DynamicResources est automatiquement chargé par tous les styles qui les référencent une fois qu'ils sont réellement chargés.

L'utilisation de DynamicResources est simple. Lorsque vous créez votre style de MonkeyText, créez comme vous le feriez normalement:

<Style TargetType="TextBlock" x:Key="MonkeyText"> 
    <Setter Property="TextAlignment" Value="Center"/> 
    <!-- etc. --> 
</Style> 

Et puis reportez-vous à lui d'utiliser ailleurs un DynamicResource:

<TextBlock Text="Hello, World!" Style="{DynamicResource MonkeyText}"/> 

Si, pour une raison quelconque, WPF ne peut pas résoudre votre DynamicResource , il échouera silencieusement sans aucune exception levée (StaticResources jette des exceptions quand le ne peut pas être résolu). Il imprimera cependant un message de débogage lorsque cela se produit. Gardez donc un œil sur la fenêtre Sortie dans Visual Studio. Comme DynamicResources fonctionne avec des ressources chargées à tout moment dans n'importe quel ordre, vous pouvez structurer vos dictionnaires de ressources comme vous le souhaitez, les mettant ainsi dans vos autres styles View et les fusionnant via l'unique App.Resources ResourceDictionary. dans app.xaml fonctionnera bien.

Vous trouverez plus de détails sur DynamicResources dans les documents MSDN pour WPF.

+0

toujours assez demandé à ce sujet moi-même, merci pour la réponse, jamais assez loin dans WPF au-delà de quelques applets .. btw, comment cascade-tu les viewmodels dépendants? avez-vous un "modèle de vue d'application" ou avez-vous un "masterviewmodel" avec "childviewmodel" avec "descendantviewmodel" – Firoso

+0

Typiquement, vous avez un modèle de vue "maître", puis vos objets de modèle sont référencés par lui et forment hiérarchie. C'est un peu plus compliqué que ça - et cela dépend un peu de la structure des données dans votre application - mais c'est la version courte –

+0

Mais que se passe-t-il si vous voulez que le MonkeyText soit utilisé sur tous les TextBlocks? Dans WPF normal, vous pouvez déclarer le style dans App.xaml et grâce à TargetType, il fonctionnera sur tous les TextBlocks. Mais en utilisant MVVM, cela ne semble pas fonctionner, sauf si je déclare DynamicResource sur tous les contrôles. – Peter

Questions connexes