如何通过 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));
}
我是 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));
}