本節學習了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>()); } }(五)項目結構
新聞熱點
疑難解答