本节学习了PRism中的UI Composition(界面组合),我认为里面最用的一个问题就是父视图区域如何把上下文(RegionContext)传到子视图,且子视图如何从获得的RegionContext中获取数据的。
本文以UI Composition QuickStart为列说明这个问题。
(一)先看看这个项目的UI结构。
(二)父区域与子区域的区域上下文(RegionContext)过程简介
首先在EmployeeSummaryView.xaml中TabControl添加如下代码:
<!--TabControl定义为一个区域, 包含EmployeeDetailsView 和 EmployeeProjectsView 将被显示--> <!--TabControl定义了 RegionContext,绑定了当前EmployeeListView中选中的Employee项--> <sdk:TabControl Grid.Row="1" AutomationProperties.AutomationId="EmployeeSummaryTabControl" Margin="8" prism:RegionManager.RegionName="TabRegion" prism:RegionManager.RegionContext="{Binding CurrentEmployee}" Width="Auto" Height="Auto" HorizontalAlignment="Stretch"> <prism:TabControlRegionAdapter.ItemContainerStyle> <Style TargetType="sdk:TabItem"> <Setter Property="HeaderTemplate"> <Setter.Value> <!--显示里面子视图TabItem的TabHead--> <DataTemplate> <TextBlock Text="{Binding ViewName}" /> </DataTemplate> </Setter.Value> </Setter> </Style> </prism:TabControlRegionAdapter.ItemContainerStyle> </sdk:TabControl> </Grid>(三)在EmployeeProjectsView.xaml.cs中添加如下代码:EmployeeDetailsView.xaml.cs相似
public EmployeeProjectsView(EmployeeProjectsViewModel employeeProjectsViewModel) { this.InitializeComponent(); // Set the ViewModel as this View's data context. this.DataContext = employeeProjectsViewModel; //在视图间共享上下文 //(1)区域上下文(RegionContext):主要用于父视图与子视图间的数据传递 // 本例,主要是EmployeeSummaryView中的TabRegion与包含在里面两个子视图EmployeeDetailsView.xaml和EmployeeProjiectsView的数据传递 //(2)在视图中获取区域上下文(RegionContext),需使用GetObservableContext方法 //(3)上下文的值可以更改,通过指定一个新的值给Value属性 //(4)不能用使用DataContext属性用于父视图和子视图的数据传递,以为DataContext只是用于View和ViewModel间的数据传递 RegionContext.GetObservableContext(this).PropertyChanged += (s, e) => employeeProjectsViewModel.CurrentEmployee = RegionContext.GetObservableContext(this).Value as Employee; }(四)关于 视图发现(View Discovery)与 视图注入(View Injection)
//视图发现(View Discovery)与 视图注入(View Injection) //(1)视图发现(View Discovery)允许将视图(View)拉人(pull)到区域(Regions)中 // RegionViewRegistry查找一个已经创建区域与之关联的所有视图(View),匹配好的View被创建,并被拉入(pull)到区域中 // 当使用这中方法,region实例不能通过名字被明确地找到来创建view和注册视图到region // 通常那些宿主在其他视图的视图有上下文需要可以被其子视图得到 //(2)视图注入(View Injection)方式:允许将视图推入到已经存在的区域,这个需要建立一个视图实例获得视图的引用,通过 // RegionViewRegistry 使用region的Add方法将view和region相关联 // 通常视图注入(View Injection)被用作当明确空间的视图作为一个区域是必要的,或者在算法上确定视图什么时候ibie显示。 //View Discovery和 View Injiection的不同 //(1)view discovery没有时间议题,比如,一个module视图加入一个view到一个还没有被创建的region中。 //(2)能很简单的检查到多个实例额在同一区域中,因为你不需要知道限制的区域的管理者找指定的region实例去注册你的视图 //(3)你可以通过RegionViewRegistry类得GetContents方法得到所有的视图关联到特定的区域. //(4)如果你需要限制区域管理你不应该用View Discorery组合,你需要要多个同时包含在同一起区域相同View的实例,因为一个区域通过 // regionManager,名字必须唯一 public class ModuleInit : IModule { private readonly IUnityContainer container; private readonly IRegionManager regionManager; [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] private MainRegionController _mainRegionController; public ModuleInit(IUnityContainer container, IRegionManager regionManager) { this.container = container; this.regionManager = regionManager; } public void Initialize() { // Register the EmployeeDataService concrete type with the container. // Change this to swap in another data service implementation. this.container.RegisterType<IEmployeeDataService, EmployeeDataService>(); // This is an example of View Discovery which associates the specified view type // with a region so that the view will be automatically added to the region when // the region is first displayed. // TODO: 03 - The EmployeeModule configures the EmployeeListView to automatically appear in the Left region (using View Discovery). // Show the Employee List view in the shell's left hand region. this.regionManager.RegisterViewWithRegion( RegionNames.LeftRegion, () => this.container.Resolve<EmployeeListView>()); // TODO: 04 - The EmployeeModule defines a controller class, MainRegionController, which programmatically displays views in the Main region (using View Injection). // Create the main region controller. // This is used to programmatically coordinate the view // in the main region of the shell. this._mainRegionController = this.container.Resolve<MainRegionController>(); // TODO: 08 - The EmployeeModule configures the EmployeeDetailsView and EmployeeProjectsView to automatically appear in the Tab region (using View Discovery). // Show the Employee Details and Employee Projects view in the tab region. // The tab region is defined as part of the Employee Summary view which is only // displayed once the user has selected an employee in the Employee List view. this.regionManager.RegisterViewWithRegion( RegionNames.TabRegion, () => this.container.Resolve<EmployeeDetailsView>()); this.regionManager.RegisterViewWithRegion (RegionNames.TabRegion, () => this.container.Resolve<EmployeeProjectsView>()); } }(五)项目结构
新闻热点
疑难解答