如何通过 DI 将参数传递给新创建的视图

How to pass parameter to new created view via DI

我是 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 & OnNaviagationTo 不起作用,因为我不是从 MainView 导航,我只是打开其他视图。 我查了非常有名的Stock Trader RI,但是,我仍然没有找到实现它的方法。

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

谢谢,

N.

我也是 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;
    }
}

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

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

但是,要使用 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 来标记它应该在导航到它时接收新创建的视图模型的视图

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

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));

        }