Silverlight MVVM MEF ViewInjection

时间:2010-03-04 17:34:02

标签: silverlight mvvm mef

由于我的标题符合流行语,我希望我能得到很多答案,或者指向正确的方向。

好的我通常做的是ViewModel,它包含ViewModel本身的列表。

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风格

好的,我有类似合同的东西

IGadget

我实施了自定义导出。

[ExportGadget(GadgetType = GadgetTypes.News)]

我有我的NewsGadgetView.xaml(实现IGadget)并导入NewsGadgetViewModel并使其自身可用作ExportGadget。

到目前为止一切顺利。有了这个,我可以创建一组小工具。

然后我有我的SidbarView.xaml,它导入了sidebarViewModel。

现在我迷路了...

我想到了像GadgetFactory这样的东西,它使用PartCreator来创建我的小工具。 但这将放在我的SidebarView.xaml中 但我想控制我的小工具添加并从我的侧边栏中删除它们。 所以我想到了像ObserveableCollection ......

我绑定到

                                                                                                                                                                          

GadgetHost是basicaly Grid,它将动态加载小工具......

那么,如何在不知道哪些小工具可用的情况下创建包含不同小工具的侧边栏,并为侧边栏和每个小工具设置ViewModel?...

感谢您的帮助......

1 个答案:

答案 0 :(得分:2)

这就是Managed Extensibility Framework的强大之处。我对现有项目基本上面临同样的挑战。

我的决心是抽象视图和区域,然后使用路由机制。

基本上,有一个区域的自定义导出,我导出一个FrameworkElement(可能是一个StackPanel,Grid等等),这些视图有一组属性,这些属性被导出为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,就可以在准备就绪时触发。