代码改变世界

prism模块化问题总结(1)

2009-03-26 14:53  Clingingboy  阅读(4786)  评论(0编辑  收藏

 

在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


问题:多个模块组成在一起,不可能是同时初始化时,全部加载的.如下图,模块未加载之前.

image

点击菜单加载一个登录的模块以后,如下图

image 

解决办法:模块初始化时,不要加载页面,注册模块的相关服务即可.

 

多个区域同时加载同个模块

如下面左右两个区域加载了同个登录控件.

image

问题:在我们注册对象时,一个控件实例是无法同时在两个区域中的.如果系统用这种同个区域使用多个模块的话,则不要注册单一实例,如

_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依然存在容器中

image

解决方法:

(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());