2010-03-04 6 views
2

depuis que mon titre est compatible Buzzword J'espère que j'obtiendrai beaucoup de réponses à ma question ou à tout pointeur vers la bonne direction. OK, ce que je fais habituellement est d'avoir un ViewModel qui contient une liste de ViewModels lui-même.Silverlight MVVM MEF ViewInjection

public class MasterViewModel 
{ 
    public ObservableCollection<DetailViewModel> DetailViewModels { get; set; } 
    public DetailViewModel Detail { get; set; } 
} 

    <ItemsControl ItemsSource="{Binding DetailViewModels}"> 
     <ItemsControl> 
      <ItemsPanelTemplate> 
       <StackPanel /> 
      </ItemsPanelTemplate> 
     </ItemsControl> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <views:DetailsView /> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

Dans cet esprit, je vais maintenant venir à mes questions. J'ai lu beaucoup de bonnes choses sur MEF et j'ai aussi vu l'échantillon de Glenn Block sur le tableau de bord mais cela ne m'a pas suffisamment aidé.

Ce que je veux faire est sidbar (comme la barre latérale de Windows). Barre latérale = StackPanel ListItems = Gadget

Buti le veulent le style MVVM

OK J'ai quelque chose comme un contrat

IGadget 

Je mis en place une commande d'exportation.

[ExportGadget(GadgetType = GadgetTypes.News)] 

J'ai mon NewsGadgetView.xaml (qui met en œuvre IGadget) et importe le NewsGadgetViewModel et se rend également disponible ExportGadget.

jusqu'ici tout va bien. Avec cela, je peux créer un ensemble de gadgets.

Ensuite, j'ai mon SidbarView.xaml qui importe un sidebarViewModel.

et maintenant je suis perdu ...

Je pensais que quelque chose comme un GadgetFactory qui utilise PartCreator pour créer mes gadgets. mais ce serait assis dans mon SidebarView.xaml Mais je veux avoir le contrôle sur mes gadgets pour les ajouter et les supprimer de ma barre latérale. donc je pensais que quelque chose comme un ObserveableCollection ...

Ce que je lie à

Le GadgetHost est la grille basicaly qui charge le gadget dynamiquement ....

Alors, comment pourrais-je créer mon barre latérale contenant différents gadgets sans savoir qui gadgets sont disponibles et ont un ViewModel pour la barre latérale, ainsi que pour chaque gadget? ...

Merci pour toute aide ....

Répondre

2

C'est ici qu'intervient la puissance du cadre d'extensibilité géré. J'ai le même défi avec un projet existant. Ma résolution consistait à extraire les vues et les régions, puis à utiliser un mécanisme de routage.

Fondamentalement, il existe une exportation personnalisée pour une région, et j'exporte un FrameworkElement (peut être un StackPanel, Grid, etc etc), Les vues ont un ensemble d'attributs, ceux-ci sont exportés en UserControl.

Un gestionnaire gère les importations à l'aide d'une collection d'importation différée. Il les assigne simplement à un dictionnaire, de sorte que nous avons des mappages d'énumération en instances de vues, puis des mappages d'enumérations de région aux instances des régions.

La table de routage attend ensuite une demande d'activation d'une vue (cela peut se produire lors du chargement), trouve l'itinéraire de la vue dans la région, puis l'insère.

Qu'en est-il du modèle de vue?

Pour plus d'informations « globale » J'utilise un contrat qui est exporté, comme ceci:

[Export(typeof(IMasterViewModel))] 
public class MasterViewModel 
{ 
} 

qui a quelque chose tous les plug-in peut-être besoin. Ensuite, j'ai un modèle de vue de base des modèles de vue « enfants » héritent de:

public class BaseViewModel 
{ 
    [Import(typeof(IMasterViewModel))] 
    public MasterViewModel MasterVM { get; set; } 
} 

Alors maintenant, ce que j'ai un XAP complètement séparé. Je vais devoir référencer certaines interfaces "communes". Donc je ne référence pas une instance du modèle de vue globale, juste le contrat. Cependant, dans mon plug-in XAP, je peux le faire:

[Export] 
public class PluginViewModel : BaseViewModel 
{ 
    etc ... etc .. 
} 

public partial class PluginControl : UserControl 
{ 
    [Import] 
    public PluginViewModel 
    { 
     get { return LayoutRoot.DataContext as PluginViewModel; } 
     set { LayoutRoot.DataContext = value; 
    } 
} 

Lorsque le modèle de vue est importé dans la vue, il importera également le modèle de vue maître, l'accès à ces autres parties. Si vous avez besoin de déclencher une action lorsque le modèle de vue est disponible, implémentez simplement IPartImportsSatisfiedNotification et vous pouvez déclencher lorsque vous êtes prêt.