prism模組化問題總結(1)
阿新 • • 發佈:2018-11-02
在prism模組化時,IRegion提供了新增View和Remove的方法.下面對一些會遇到的問題進行討論。
以下為Demo的Shell,一個Menu的Region,兩個內容區域.
<StackPanel> <Menu cal:RegionManager.RegionName="TopRegion" ></Menu> <StackPanel Orientation="Horizontal"> <GroupBox Header="LeftRegion" cal:RegionManager.RegionName="LeftRegion" Width="300" Height="600"> </GroupBox> <GroupBox Header="RightRegion" cal:RegionManager.RegionName="RightRegion" Width="300" Height="600"> </GroupBox> </StackPanel> </StackPanel>
動態載入模組UI
問題:多個模組組成在一起,不可能是同時初始化時,全部載入的.如下圖,模組未載入之前.
點選選單載入一個登入的模組以後,如下圖
解決辦法:模組初始化時,不要載入頁面,註冊模組的相關服務即可.
多個區域同時載入同個模組
如下面左右兩個區域載入了同個登入控制元件.
問題:在我們註冊物件時,一個控制元件例項是無法同時在兩個區域中的.如果系統用這種同個區域使用多個模組的話,則不要註冊單一例項,如
_unityContainer.RegisterType<LoginView>(new ContainerControlledLifetimeManager());
_regionManager.Regions["LeftRegion"].Add(_unityContainer.Resolve<LoginView>());
_regionManager.Regions["RightRegion"].Add(_unityContainer.Resolve<LoginView>());
解決辦法:所以當你載入此模組時,需保證載入的控制元件是新的一個例項.
_regionManager.Regions["LeftRegion"].Add(new LoginView()); _regionManager.Regions["RightRegion"].Add(new LoginView());
區域UI子區域巢狀
問題:子控制元件區域再新增子控制元件時如上一樣,依然需要重新例項化
//second time will throw exception
_regionManager.AddToRegion("LoginRegion", _unityContainer.Resolve<HelloWorldView>());
當LoginRegionView移除之後,HelloWorldView依然存在容器中
解決方法:
(1)同上,還是需要一個新的例項物件.
(2)將LoginRegionView也存在容器中,也可以解決此問題,但不符合多個區域同時載入同個模組的需求
延遲將UI介面新增到區域
載入ui最好是延遲載入(按需載入),這樣程式的初始化和執行速度都會加快.有時候我們會犯一些錯誤,向一個Region中新增一個View.
如點選MenuItem新增一個View,這個View應該是MenuItem的Click事件觸發後才初始化.如下程式碼:
private void AddViewToRegion(object view)
{
MenuItem regionItem = new MenuItem() { Header = "載入模組" };
regionItem.Click+=new RoutedEventHandler((o,e) =>
{
_regionManager.Regions["region"].Add(view);
});
}
然後呼叫,傳入的引數是一個UserControl,注意這裡傳入引數的時候就已經初始化了.不符合要求.
AddViewToRegion(new HelloWorldView());
用Func<TResult> 泛型委託來延遲初始化
現在程式碼如下:
private void AddViewToRegion(Func<object> view)
{
MenuItem regionItem = new MenuItem() { Header = "載入模組" };
regionItem.Click+=new RoutedEventHandler((o,e) =>
{
_regionManager.Regions["region"].Add(view());
});
}
AddViewToRegion(() => new HelloWorldView());