2010-03-04 61 views
2

因爲我的標題符合時髦詞我希望我會得到很多答案我的問題或任何指向正確的方向。Silverlight MVVM MEF ViewInjection

好吧,我通常做的是有一個ViewModel其中包含ViewModels本身的列表。

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> 

考慮到這一點,我現在來看看我的問題。我閱讀了關於MEF的很多好消息,並且看到了Glenn Block的儀表板樣本,但這並沒有幫到我。

我想要做的是sidbar(就像windows邊欄)。 邊欄=的StackPanel 時listItems =小工具

布提希望它MVVM風格

OK我有類似的合同

IGadget 

一個我實現了一個自定義的出口。

[ExportGadget(GadgetType = GadgetTypes.News)] 

我有我的NewsGadgetView.xaml(實現IGadget)和進口NewsGadgetViewModel,也使得本身可作爲ExportGadget。

迄今爲止好。有了這個,我可以創建一組小工具。

然後我有我的SidbarView.xaml導入sidebarViewModel。

,現在我迷路了......

我認爲像它使用PartCreator創建我的小玩意GadgetFactory。 但這會坐在我的SidebarView.xaml 但我想控制我的小工具來添加和從我的邊欄刪除它們。 所以我想到了類似的ObserveableCollection ...

對此我綁定到

的GadgetHost是basicaly電網將dynamicaly加載小工具...

那麼我將如何創建一個包含不同的工具欄我不知道這小工具可用,有一個視圖模型爲工具條以及爲每個小工具?...

感謝您的幫助....

回答

2

這就是管理擴展性框架的威力所在。我對現有項目基本上有同樣的挑戰。

我的決議是抽象的意見和地區,然後使用路由機制。

基本上,有一個區域的自定義導出,我導出一個FrameworkElement(可能是一個StackPanel,網格等等等等),這些視圖有一組屬性,那些導出爲UserControl。

管理器使用惰性導入集合處理導入。它只是將這些分配給字典,因此我們將枚舉映射到視圖實例,然後將區域枚舉映射到區域實例。

路由表然後等待激活視圖的請求(這可能在加載時發生),並查找從視圖到區域的路由,然後插入它。

視圖模型怎麼樣?

對於「全球性」信息,我使用的是出口合同,是這樣的:

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

這有什麼每個插件都可能需要。然後,我有「子」視圖模型繼承基礎視圖模式:

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

現在讓我們說,我有一個完全獨立的XAP。我將需要引用一些「通用」接口。所以我沒有引用全局視圖模型的實例,只是合同。然而,我的插件XAP內,我可以這樣做:

[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; 
    } 
} 

當視圖模型導入到視圖,也將導入主視圖模型,提供訪問這些其他部分。如果您需要在視圖模型可用時觸發某些操作,只需實現IPartImportsSatisfiedNotification,並且可以在準備就緒時觸發。