【问题标题】:Reusing Views and Viewmodel with MEF & Silverlight使用 MEF 和 Silverlight 重用视图和视图模型
【发布时间】:2011-02-21 17:04:13
【问题描述】:

这是我想做的:

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

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

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

我的问题实际上是当我导航到已经加载的这个页面时(例如从 myapp.aspx#view1/ 2到myapp.aspx#view1/3)(我打算在ContentLoader类的BeginLoad中做这个) 如果我获得了视图模型,我可以通过更改当前 itemId 属性来完成我想要的操作,该属性可以通过绑定刷新视图。

如果您有什么要提议的,非常感谢。

【问题讨论】:

    标签: silverlight-4.0 mef mvvm-light


    【解决方案1】:

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

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

    不过,在这里推出您自己的产品相当容易,尤其是因为您已经在使用 MEF。只需创建一个服务来处理消息传递,并将其导入两个端点。

    【讨论】:

      【解决方案2】:

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

      我认为,有了信使,我将无法在视图中使用带有 url 的导航?否则我并没有真正弄清楚你向我提出了什么建议。

      我想采用的算法是:

      • 导航("...asp#MyView1/1")
        • MyView1 是当前视图?
          • 是的,那么我想获取当前视图的视图模型并将其 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();
      

      谢谢。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-04
        • 1970-01-01
        • 2011-12-25
        • 1970-01-01
        • 2011-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多