2010-01-04 9 views
2

Alors que je supprime de plus en plus de problèmes liés à MVVM avec mon application actuelle, d'autres continuent à apparaître. :)Application de MVVM à un ItemsControl rempli de UserControls

L'implémentation actuelle que j'essaie de remplacer implique un StackPanel dont les enfants sont générés plus ou moins dynamiquement (en regardant dans un fichier de configuration). Chaque enfant est une instance d'un UserControl. Auparavant, j'attribuais un nom au StackPanel, puis dans le gestionnaire d'événements Window_Loaded, je déterminais simplement le nombre d'enfants nécessaire, instanciez un UserControl pour chacun d'entre eux, et j'attribuais également un UserControl à un ID que je connaissais. la source appropriée pour les boutons cliqués sur une instance UserControl particulière; chaque UserControl a 3 boutons dessus. Donc, je sais que je veux lier le StackPanel à une collection. Bien sûr, ce n'est pas possible, car j'ai besoin d'utiliser quelque chose qui dérive de ItemsControl, comme ListBox ou ListView (ou même ItemsControl lui-même). Pour le rendre facile dans la première itération de MVVM-ifying, je vais juste utiliser un ListBox.

Maintenant, la question est de savoir si mon ObservableCollection dans le code-behind est une ObservableCollection? Je crois que cela signifie que peu importe comment je peau ma GUI, ce ListBox aura toujours des enfants qui ont l'air cependant qu'ils font dans le fichier XAML de MyUserControl. Je voudrais aussi que cela soit personnalisable, mais je suppose que cela signifie que je dois aussi appliquer le pattern MVVM à UserControl.

Répondre

5

Si vous souhaitez que chacun de vos éléments de liste possède différents modèles et que vous souhaitiez conserver un style MVVM, il vaut mieux ne pas penser en termes de UserControls.

Vous pouvez avoir votre vue principale pour avoir un ListBox lié à une collection observable d'instances View Model. Si vous configurez vos modèles de données pour mapper les classes ViewModel à leur UserControl approprié, vous n'avez pas besoin de charger explicitement UserControls. Il vous suffit de lier ItemsControl à votre collection de ViewModels et de laisser les templates de données s'occuper de la construction le UserControl correct pour cette VM.

+0

Je n'ai pas besoin de chaque ListItem pour avoir un modèle différent, mais je veux absolument m'en tenir à un style MVVM. Il s'avère que je ne peux pas faire ce que j'avais proposé de toute façon, puisque UserControl référence déjà le ViewModel, et donc je finirais avec une référence circulaire. Je vais donner à cette approche ViewModel un coup de feu et voir où cela me mène. Merci! – Dave

+0

Ouais - Chaque élément peut être une classe ViewModel distincte, ce qui signifie qu'il obtiendra son propre modèle (si vous avez une configuration DataTemplate pour chaque ViewModel pour le mapper à une vue appropriée). Cela peut être un UserControl distinct. Je le fais tout le temps - il en fait une liste de machines virtuelles, complètement séparées des vues - MVVM pur :) –

+0

Je me suis fait distraire juste maintenant en essayant d'aider quelqu'un dans le forum Expression Blend, mais je vais regarder dans cette méthode de "lier" une VM à un V en utilisant DataTemplates. Ce n'est pas quelque chose que j'ai déjà fait, ou même entendu parler. J'adore essayer d'appliquer MVVM - je trouve que j'en apprends beaucoup plus sur WPF tout au long du processus! Merci pour votre suggestion! – Dave

1

Votre collection ne doit pas être un ObservableCollection si ce n'est pas obligatoire. La partie "Observable" de ObservableCollection consiste simplement à fournir des événements pour avertir les autres que la collection a changé, elle n'est en aucun cas liée à la représentation visuelle.

ObservableCollection est très bien adapté pour MVVM à cause de toute la notification des événements qu'elle fournit, mais en fin de compte, si vous utilisez un List<T> ou un ObservableCollection<T> ne fait aucune différence dans la façon dont les choses apparaissent visuellement à un moment donné dans le temps.

+0

Merci pour la clarification concernant ObservableCollections.Je me suis dit que je voudrais utilisez-le pour relier n'importe quel type de collection, mais vous m'avez rappelé que c'est principalement pour la notification de modification.Sur mon application, je n'ai pas vraiment le contenu de ComboBoxes et autres changements dynamiques - ils sont remplis une seule fois via liaison de données, alors peut-être que je devrais revenir en arrière et les changer en quelque chose avec (éventuellement) moins de frais généraux – Dave

+0

@ Matsumoto: Si vous savez que les éléments ne changeront jamais, vous pouvez aussi bien utiliser une liste - mais si vous pouvez , à un moment donné, décidez d'ajouter/supprimer des éléments de votre liste, je voudrais juste utiliser une ObservableCollection .La plupart des "overhead" est vraiment seulement un problème quand les choses ch ange, dans ce cas, vous voulez le surcoût supplémentaire ... –

+0

Ne pas casser MVVM par crainte de surcharge possible. Optimisation prématurée ... –