本節(jié)學(xué)習(xí)了PRism中的UI Composition(界面組合),我認(rèn)為里面最用的一個(gè)問(wèn)題就是父視圖區(qū)域如何把上下文(RegionContext)傳到子視圖,且子視圖如何從獲得的RegionContext中獲取數(shù)據(jù)的。
本文以UI Composition QuickStart為列說(shuō)明這個(gè)問(wèn)題。
(一)先看看這個(gè)項(xiàng)目的UI結(jié)構(gòu)。

(二)父區(qū)域與子區(qū)域的區(qū)域上下文(RegionContext)過(guò)程簡(jiǎn)介
首先在EmployeeSummaryView.xaml中TabControl添加如下代碼:

<!--TabControl定義為一個(gè)區(qū)域, 包含EmployeeDetailsView 和 EmployeeProjectsView 將被顯示--> <!--TabControl定義了 RegionContext,綁定了當(dāng)前EmployeeListView中選中的Employee項(xiàng)--> <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)區(qū)域上下文(RegionContext):主要用于父視圖與子視圖間的數(shù)據(jù)傳遞 // 本例,主要是EmployeeSummaryView中的TabRegion與包含在里面兩個(gè)子視圖EmployeeDetailsView.xaml和EmployeeProjiectsView的數(shù)據(jù)傳遞 //(2)在視圖中獲取區(qū)域上下文(RegionContext),需使用GetObservableContext方法 //(3)上下文的值可以更改,通過(guò)指定一個(gè)新的值給Value屬性 //(4)不能用使用DataContext屬性用于父視圖和子視圖的數(shù)據(jù)傳遞,以為DataContext只是用于View和ViewModel間的數(shù)據(jù)傳遞 RegionContext.GetObservableContext(this).PropertyChanged += (s, e) => employeeProjectsViewModel.CurrentEmployee = RegionContext.GetObservableContext(this).Value as Employee; }
(四)關(guān)于 視圖發(fā)現(xiàn)(View Discovery)與 視圖注入(View Injection)

//視圖發(fā)現(xiàn)(View Discovery)與 視圖注入(View Injection) //(1)視圖發(fā)現(xiàn)(View Discovery)允許將視圖(View)拉人(pull)到區(qū)域(Regions)中 // RegionViewRegistry查找一個(gè)已經(jīng)創(chuàng)建區(qū)域與之關(guān)聯(lián)的所有視圖(View),匹配好的View被創(chuàng)建,并被拉入(pull)到區(qū)域中 // 當(dāng)使用這中方法,region實(shí)例不能通過(guò)名字被明確地找到來(lái)創(chuàng)建view和注冊(cè)視圖到region // 通常那些宿主在其他視圖的視圖有上下文需要可以被其子視圖得到 //(2)視圖注入(View Injection)方式:允許將視圖推入到已經(jīng)存在的區(qū)域,這個(gè)需要建立一個(gè)視圖實(shí)例獲得視圖的引用,通過(guò) // RegionViewRegistry 使用region的Add方法將view和region相關(guān)聯(lián) // 通常視圖注入(View Injection)被用作當(dāng)明確空間的視圖作為一個(gè)區(qū)域是必要的,或者在算法上確定視圖什么時(shí)候ibie顯示。 //View Discovery和 View Injiection的不同 //(1)view discovery沒(méi)有時(shí)間議題,比如,一個(gè)module視圖加入一個(gè)view到一個(gè)還沒(méi)有被創(chuàng)建的region中。 //(2)能很簡(jiǎn)單的檢查到多個(gè)實(shí)例額在同一區(qū)域中,因?yàn)槟悴恍枰老拗频膮^(qū)域的管理者找指定的region實(shí)例去注冊(cè)你的視圖 //(3)你可以通過(guò)RegionViewRegistry類得GetContents方法得到所有的視圖關(guān)聯(lián)到特定的區(qū)域. //(4)如果你需要限制區(qū)域管理你不應(yīng)該用View Discorery組合,你需要要多個(gè)同時(shí)包含在同一起區(qū)域相同View的實(shí)例,因?yàn)橐粋€(gè)區(qū)域通過(guò) // 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>()); } }
(五)項(xiàng)目結(jié)構(gòu)

新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注