使用MEF和&amp ;;重用视图和视图模型Silverlight的

时间:2011-02-21 17:04:14

标签: silverlight-4.0 mef mvvm-light

以下是我想做的事情:

我有一个使用导航框架和MEF的Silverlight应用程序。 (像这样:http://msdn.microsoft.com/en-us/magazine/gg535672.aspx) 该应用程序由一组按钮组成。每个按钮单击加载视图及其关联的ViewModel。

在这些视图中,我有一个包含项目的列表,当我点击每个项目时,它会刷新此视图中的一种子视图。

我想创建一个导航系统:例如myapp.aspx#view1 / 2,其中2实际上是列表中单击的项目。如果我点击其中一个按钮,它将加载一个默认项目并刷新所有视图,但是当我点击一个项目时,我不想刷新所有视图但只是视图的某些部分(我不想要创建另一个视图实例和viewmodel)。

我的问题实际上是,当我导航到已经加载的页面时,我想获得对现有视图或视图模型的引用的最佳实践(例如来自myapp.aspx#view1 / 2到myapp.aspx#view1 / 3)(我打算在ContentLoader类的BeginLoad中执行此操作) 如果我获得了viewmodel,我可以通过更改例如当前的itemId属性来实现我想要的,这可以通过绑定来刷新视图。

如果你有什么建议,请多谢。

2 个答案:

答案 0 :(得分:1)

一种常见的方法是使用某种形式的Messenger来执行此类操作。项目的单击可以触发发送消息,附加项目。有问题的ViewModel将是订阅者,并编辑其当前设置(即:它是ItemId,这将触发绑定刷新)。

最常见的实现通常类似于Messenger service in MVVM Light

在这里推广你自己很容易,特别是因为你已经在使用MEF了。只需创建一个服务来处理消息传递,然后将其导入两个端点。

答案 1 :(得分:0)

实际上,当我点击某个项目时,我会优先使用URI在我的应用程序中导航,但如果我使用URI,则整个视图正在重新加载而不是我想要的特定部分。

使用信使,我认为在视图中我无法使用网址导航?或者我没有弄清楚你向我提出的建议。

我想采用的算法是:

  • 引导(” ... ASP#MyView1 / 1" )
    • MyView1是当前视图?
      • 是的然后我想获取当前视图的viewmodel并将其更改为ItemId属性1
      • 不,然后将创建视图

我想在那里实现这个算法:(在我的CompositionNavigationContentLoader类中,这是每个导航实例化视图的地方)

   public IAsyncResult BeginLoad(Uri targetUri, Uri currentUri, AsyncCallback userCallback, object asyncState)
    {
        // Convert to a dummy relative Uri so we can access the host.
        var relativeUri = new Uri("http://" + targetUri.OriginalString, UriKind.Absolute);

        // Get the factory for the ViewModel.
        var viewModelMapping = ViewModelExports.FirstOrDefault(o => o.Metadata.Key.Equals(relativeUri.Host, StringComparison.OrdinalIgnoreCase));
        if (viewModelMapping == null)
            throw new InvalidOperationException(
                String.Format("Unable to navigate to: {0}. Could not locate the ViewModel.", targetUri.OriginalString));

        // Get the factory for the View.
        var viewMapping = ViewExports.FirstOrDefault(o => o.Metadata.ViewModelContract == viewModelMapping.Metadata.ViewModelContract);
        if (viewMapping == null)
            throw new InvalidOperationException(
                String.Format("Unable to navigate to: {0}. Could not locate the View.", targetUri.OriginalString));

        // Resolve both the View and the ViewModel.
        var viewFactory = viewMapping.CreateExport();
        var view = viewFactory.Value as Control;
        var viewModelFactory = viewModelMapping.CreateExport();
        var viewModel = viewModelFactory.Value as IViewModel;

        // Attach ViewModel to View.
        view.DataContext = viewModel;
        viewModel.OnLoaded();

感谢。