【问题标题】:How to pass parameter to new created view via DI如何通过 DI 将参数传递给新创建的视图
【发布时间】:2016-10-20 06:53:18
【问题描述】:

我对 PRISM 还是很陌生,我不得不说,我每天都越来越喜欢它!目前,我正在努力解决如何将参数传递给新创建的视图(通过依赖注入)的问题。我的情况如下: 用户单击一个按钮,屏幕右侧会创建一个新视图。我正在这样做,如下:

IRegion 区域 = this._regionManager.Regions[RegionNames.ActionRegion];

 object boxView = region.GetView("BoxDetailsView");
 if (boxView == null)
        {
       boxView = ServiceLocator.Current.GetInstance<BoxDetailsView>();
            region.Add(boxView, "BoxDetailsView");
        }

        region.Activate(boxView);

这很好用。但是,我确实需要将参数传递给该视图,但我不知道如何。 OnNavigationFrom 和 OnNavigationTo 不起作用,因为我不是从 MainView 导航,我只是打开其他视图。 我确实检查了非常著名的 Stock Trader RI,但是我仍然没有找到完成它的方法。

我觉得我很接近,但做错了一些小事。有人可以帮忙吗?

谢谢,

N.

【问题讨论】:

    标签: wpf prism


    【解决方案1】:

    我建议使用导航框架。只需使用 RequestNavigate 并通过方法调用传递参数。然后让您的 View/ViewModel 实现 INavigationAware,然后您就可以访问您传递的参数。

    【讨论】:

      【解决方案2】:

      我也是 prism 的新手,但在我的项目中,我使用 RegionContext 将参数作为视图模型传递给子视图。 (我用Unity解析视图)

      xaml 中的区域 (source):

          <TabControl 
          regions:RegionManager.RegionName="{x:Static inf:RegionNames.ServerTabPartRegion}" 
          regions:RegionManager.RegionContext="{Binding CurrentServer, Mode=OneWay}">
          </TabControl>
      

      查看注册(source

          public void Initialize()
          {
              _regionManager.RegisterViewWithRegion(RegionNames.ServerTabPartRegion, CreateView);
          }
      
          private object CreateView()
          {
              return ServerTabViewHelper.RegisterView<OnlinePlayers, ServerInfo, ServerMonitorPlayerViewModel>(_container,
                  "serverInfo");
          }
      

      获取参数的助手(source

      public static class ServerTabViewHelper
      {
          public static TView RegisterView<TView, TViewParameter, TViewModel>(IUnityContainer container, string parameterName)
              where TView : FrameworkElement where TViewParameter : class
          {
              var view = container.Resolve<TView>();
              var context = RegionContext.GetObservableContext(view);
              context.PropertyChanged += (s, e) =>
              {
                  var obs = s as ObservableObject<object>;
                  if (obs != null)
                  {
                      var serverInfo = obs.Value as TViewParameter;
                      var vm = container.Resolve<TViewModel>(new ParameterOverride(parameterName, serverInfo));
                      view.DataContext = vm;
                  }
              };
              return view;
          }
      }
      

      【讨论】:

        【解决方案3】:

        在导航时解析视图模型的优点是视图模型始终处于初始化状态(前提是您在导航时拥有所有可用数据以防止延迟)。

        不过,要使用 prism,您必须使用修改后的 RegionNavigationService,因为该功能不会包含在框架中(截至目前,请参阅 this issue)...

        扩展ExecuteNavigation方法:

        [...update journal...]
        
        // Create and set the view model based on the navigation context
        var viewAsDependencyObject = view as DependencyObject;
        if (viewAsDependencyObject != null)
        {
            var createViewModelOnNavigateTo = ViewModelLocator.GetCreateViewModelOnNavigateTo( viewAsDependencyObject );
            if (createViewModelOnNavigateTo)
                ViewModelLocator.Bind( view, _viewModelProvider.CreateViewModel( viewAsDependencyObject, navigationContext ) );
        }
        
        [...inform view...]
        

        其他变化包括:

        • _viewModelProvider :类似于ViewModelLocator 的服务,它从NavigationContext 创建视图模型
        • CreateViewModelOnNavigate :类似于AutoWireViewModel 的附加属性,用于标记在导航到它时应该接收新创建的视图模型的视图

        【讨论】:

          【解决方案4】:

          感谢大家的建议和提示!我真的很感激!我认为布赖恩的建议是最简单的,我就这样解决了:

          IRegion 区域 = this._regionManager.Regions[RegionNames.ActionRegion];

                  object boxView = region.GetView("BoxDetailsView");
                  if (boxView == null)
                  {
                      boxView = ServiceLocator.Current.GetInstance<BoxDetailsView>();
                      region.Add(boxView, "BoxDetailsView");
                      // Navigate to view
                      var parameters = new NavigationParameters();
                      parameters.Add("BOXID", param);
                      _regionManager.RequestNavigate(RegionNames.ActionRegion, new Uri("BoxDetailsView" + parameters, UriKind.Relative));
          
                  }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-01-17
            • 1970-01-01
            • 2011-06-04
            • 2011-12-09
            • 2018-09-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多