Prism 学习(一)

2017-05-14 11:41:18来源:cnblogs.com作者:积跬步---行千里人点击

转载自:http://www.cnblogs.com/Clingingboy/archive/2009/01/07/prism_part2.html

  本篇将介绍Prism中Region的使用.

 本篇Demo下载

在这里我们统一prism里面一些名字的称谓.

1.Shell 主程序容器

2.Region 内容区域

3.Module 模块

4.wpf 不是特殊情况,就是指wpf和silverlight

一.wpf的内容控件

    继承自ContentControl控件的,我们称之为内容控件.

<ContentControl Content=""></ContentControl>

ContentControl控件定义了一个Content,在没有框架的情况下,也可以将其作为一个内容区域.然而为了满足ui的需求,我们还需要各种不同的控件来当内容区域,如TabControl,DockPanel,Selector等。有些控件则继承自ItemsControl属于集合控件,不属于内容控件.但他们根据不同需求,同时都可以当容器使用,但他们的使用方式却不同.

为了统一对内容区域的操作,prism提供了一种适配模式,也可以说提供了控件与Region的映射关系.将不同可以作为容器的控件的操作方式统一为Region的操作方式.

prism内置有三种控件可以作为内容区域适配对象

  1. ContentControl
  2. ItemsControl
  3. Selector

看起来只有三个,但是只要是继承自这三个控件的其他控件也可以.下面介绍使用方法.

二.Region的基本操作,以下以Hello World为示例

1.在Shell中注册内容区域

如下代码,http://www.codeplex.com/CompositeWPF是prism注册的命名空间.

用RegionManager的附加属性RegionName注册了一个名叫MainRegion的内容区域

<Window x:Class="HelloWorldSample.Shell"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:cal="http://www.codeplex.com/CompositeWPF"    Title="Composite Application Library Sample" Width="400" Height="300">    <ContentControl cal:RegionManager.RegionName="MainRegion"/></Window>

2.通过IRegionManager获取已注册的内容区域

已注册的Region将保存在IRegionManager的Regions集合里面,根据注册的名字取出Region,将返回一个IRegion对象.

IRegion mainRegion = this.regionManager.Regions["MainRegion"];

3.在Region中添加内容

首先定义一个用户控件

<UserControl x:Class="HelloWorld.Views.HelloWorldView"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">    <Grid>        <TextBlock Text="Hello World" Foreground="Green"                    HorizontalAlignment="Center" VerticalAlignment="Center"                    FontFamily="Calibri" FontSize="24" FontWeight="Bold"></TextBlock>    </Grid></UserControl>

通过IRegion的Add方法添加用户控件.以下是一个简单模块的完成代码,当这个模块加载时,会默认执行Initialize方法.

public class HelloWorldModule : IModule{    private readonly IRegionManager regionManager;    public IUnityContainer container { get; set; }    public HelloWorldModule(IRegionManager regionManager, IUnityContainer container)    {        this.regionManager = regionManager;        this.container = container;    }    public void Initialize()    {        RenderHelloWorldView();     }    void RenderHelloWorldView()    {        IRegion mainRegion = this.regionManager.Regions["MainRegion"];        mainRegion.Add(new HelloWorldView());    }}

下图表达以上三个步骤的意思.

image

三.Region对View的操作

1.可以将以下操作并为一类.Add方法有三个重载,第三个方法下面再解释.当给View指定一个名字时,可以通过GetView方法获取View,然后通过Remove方法删除.

        IRegionManager Add(object view);        IRegionManager Add(object view, string viewName);        IRegionManager Add(object view, string viewName, bool                               createRegionManagerScope);        void Remove(object view);        object GetView(string viewName); 2.激活和停用View
默认情况下,当一个View添加到Region当中,都被记做是处于活动状态。IRegion提供了2个集合和2个方法来控制View的活动状态.Activate方法将View转为可活动状态,Deactivate方法则冻结了View的使用.两个方法的调用将使Views和ActiveViews两个集合属性发生变化.IViewsCollection实现了INotifyCollectionChanged接口了,所以当集合发生变化时会触发一个事件来引发ui界面发生变化,这个事件的引发由Region和控件的适配器来完成.如何自定义RegionAdapter将在下次介绍,回头再看到这里就非常清楚了.
 
        IViewsCollection Views { get; }        IViewsCollection ActiveViews { get; }        void Activate(object view);        void Deactivate(object view);   

四.注册子区域Region

1.在Region中添加的View同时也可以注册Region的,但这个被添加的View必须依靠依赖注入的功能才可以.请看以下示例

<UserControl x:Class="HelloWorld.Views.HelloWorldViewAgain"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:cal="http://www.codeplex.com/CompositeWPF"    Height="300" Width="300">    <Grid>        <StackPanel>            <TextBlock Text="HelloWorldViewAgain"></TextBlock>            <TextBlock Text="HelloWorldView Loading"></TextBlock>            <ItemsControl cal:RegionManager.RegionName="HelloWorldViewAgain"/>            <TextBlock Text="HelloWorldView Loaded"></TextBlock>        </StackPanel>    </Grid></UserControl>

在Shell的Region中添加HelloWorldViewAgain

void RenderHelloWorldViewAgain(){    IRegion mainRegion = this.regionManager.Regions["MainRegion"];    HelloWorldViewAgain viewAgain = container.Resolve<HelloWorldViewAgain>();    mainRegion.Add(viewAgain, "MainRegion");    viewAgain.DisplayHelloWorldView();}

DisplayHelloWorldView方法则在定义的HelloWorldViewAgain的Region添加了HelloWorldView

public void DisplayHelloWorldView(){    IRegion secondRegion = this.regionManager.Regions["HelloWorldViewAgain"];    secondRegion.Add(new HelloWorldView());}

下图表达了以上步骤的意思

image

2.设定RegionManager的管理范围

默认情况下,当注册一个Region的时候,RegionManager会将其加入到其Regions集合当中.

<ContentControl  x:Name=”panel” cal:RegionManager.RegionName="MainRegion"/>

这个Regions属性属于ContentControl的附加属性,可以通过RegionManager的GetRegionManager方法获取该控件的Region集合.

回头再看上面的一个Add方法.

IRegionManager Add(object view, string viewName, bool createRegionManagerScope);

在添加Region中添加一个View的时候,你可以指定是否重新设定RegionManager的范围.如果设置为True的话,将会调用CreateRegionManager方法为当前的View重新创建一个RegionManager.这就说明了如果创建的View中注册了一个Region,改Region是不知道其存在哪个RegionManager里面的.

现在我们重新更改上面的RenderHelloWorldViewAgain方法,添加View时,

第三个参数设置为True,如下

void RenderHelloWorldViewAgain(){    IRegion mainRegion = this.regionManager.Regions["MainRegion"];    HelloWorldViewAgain viewAgain = container.Resolve<HelloWorldViewAgain>();    mainRegion.Add(viewAgain, "HelloWorldViewAgain",true);    viewAgain.DisplayHelloWorldView();}

这时HelloWorldViewAgain这个View已注册的Region,就很难知道其在哪个RegionManager,现在DisplayHelloWorldView方法更改如下

public void DisplayHelloWorldView(){    var view=this.regionManager.Regions["MainRegion"].GetView("HelloWorldViewAgain") as DependencyObject;    IRegion region=RegionManager.GetRegionManager(view).Regions["HelloWorldViewAgain"];    region.Add(new HelloWorldView(), "hello");}

这种做法虽然可以避免Region重名等一些问题,但为获取Region的RegionManager也有一些麻烦.

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台