博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从PRISM开始学WPF(三)Prism-Region?
阅读量:6247 次
发布时间:2019-06-22

本文共 5931 字,大约阅读时间需要 19 分钟。

原文:

0x3 Region

regions

Regions是应用程序UI的逻辑区域,它很像一个PlaceHolder,Views在Regions中展现,很多种控件可以被用作Region :ContentControl、ItemsControl、ListBox、TabControl。

简单的说,就是一个容器(区域适配器),用来装载Views的。这像WinForms中的Container控件Panel,里面可以放置其他控件。在PRISM中,Views也是用户控件(UserControl

Region的注册方式:

​ 在MainWindow.xaml中:

从这里开始,我们就不得不面对 XAML了。继续引用维基百科的介绍:

XAML(Extensible Application Markup Language)是(WPF)的一部分,是开发的一种基于、基于声明,用于初始化结构化值和对象的,它有着的外观,又揉合了XML语法的本质,例如:可以使用<Button>标签设置按钮Button

(⊙﹏⊙)。。。

好,这个很简单,不需要介绍了。然后我们看代码,首先在头部引入命名空间xmlns:prism="http://prismlibrary.com/",这个prism是别名,你也可以像上面的x一样将他命名成其他你想要的名字比如sm ,当然了我们默认使用prism这样比较符合命名规范,然后在Grid控件里面,新建了了一个ContentControl,作为Region的目标,并且给他取了一个名字ContentRegion

私人定制Region控件

是不是所有控件都可以被用作Region了吗?我们来试一下,为将上面没有列出的StackPanel指定Region,上面Gird块的代码变成这样:

似乎看上去一切正常,让我们来启动他。

Oops!!!程序并没有按照我们想象的那样启动,而是抛给了我们一个异常:

Prism.Regions.UpdateRegionsException: 'An exception occurred while trying to create region objects.

Prism在生成一个Region对象的时候报错了,看上去,StackPanel并不支持用作Region。那么有其他的方法让他可以被用作Region吗?因为我们很喜欢用StackPanel啊( ﹁ ﹁ ) ~→(不要管我为什么喜欢,你不,我就偏要) 这难不倒Prism,毕竟创建Region对象就是他自己的事情,做分内的事应该没问题的。

你需要为一个将被用作Region的添加RegionAdapter(适配器)。RegionAdapter的作用是为特定的控件创建相应的Region,并将控件与Region进行绑定,然后为Region添加一些行为。一个RegionAdapter需要实现IRegionAdapte接口,如果你需要自定义一个RegionAdapter,可以通过继承RegionAdapterBase类来省去一些工作。

那,为什么ContentControl就可以呢?因为:

The Composite Application Library provides three region adapters out-of-the-box:

  • ContentControlRegionAdapter. This adapter adapts controls of type System.Windows.Controls.ContentControl and derived classes.
  • SelectorRegionAdapter. This adapter adapts controls derived from the class System.Windows.Controls.Primitives.Selector, such as the System.Windows.Controls.TabControl control.
  • ItemsControlRegionAdapter. This adapter adapts controls of type System.Windows.Controls.ItemsControl and derived classes.

因为这三个是内定的(蛤蛤),就是已经帮你实现了RegionAdapter。接下来,我们看看怎么为StackPanel实现RegionAdapter。

  • step1 新建一个类StackPanelRegionAdapter.cs,继承RegionAdapterBase
using Prism.Regions;using System.Windows;using System.Windows.Controls;namespace Regions.Prism{    public class StackPanelRegionAdapter : RegionAdapterBase
{ public StackPanelRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory) { } protected override void Adapt(IRegion region, StackPanel regionTarget) { region.Views.CollectionChanged += (s, e) => { if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) { foreach (FrameworkElement element in e.NewItems) { regionTarget.Children.Add(element); } } //handle remove }; } protected override IRegion CreateRegion() { return new AllActiveRegion(); } }}
  • setp2Bootstrapper注册绑定
protected override RegionAdapterMappings ConfigureRegionAdapterMappings()        {            RegionAdapterMappings mappings = base.ConfigureRegionAdapterMappings();            mappings.RegisterMapping(typeof(StackPanel), Container.Resolve
()); return mappings; }

这个具体中间是怎么个道道道,先不管,因为那要看Prism的源码了。不管怎样,我们现在可以为StackPanel实现用作Region了。我们再运行刚才抛给我们异常的程序,是不是已经跑起来了呢?

注册视图

指定了Region,接下来就为Region指定View了。

在Views目录下面,新建一个UserControl,并在Grid控件内,加一个TextBlock,写上字,标识这是View A。

依旧省去了大部分头部引用,代码都是在Prism-Samples-Wpf里的,这里贴出来仅方便大家无源码阅读

我们现在想要,在上一小节制定的Region内显示View A,怎么做呢?我们来看MainWindow的code-behind,即:MainWindow.xaml.cs

using Prism.Regions;using System.Windows;namespace ViewDiscovery.Views{    ///     /// Interaction logic for MainWindow.xaml    ///     public partial class MainWindow : Window    {        public MainWindow(IRegionManager regionManager)        {            InitializeComponent();            //view discovery            regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));        }    }}

看上去,他只用了一行代码就实现了,在Region中显示ViewA。可仔细看一下,这好像哪不太一样。最早我们的MainWindow.xaml.cs的构造函数是没有参数的,这里多了一个IRegionManager类型的参数regionManager,是不是很眼熟?

依赖注入容器

prism是使用依赖注入容器实现依赖注入的,这里我们使用的是Unity,Prism同样支持Mef容器实现依赖注入。

如果使用 Unity 实例化一个类,该类的构造函数依赖一个或多个其他类,则 Unity 会为构造函数自动创建参数中指定的被依赖的类的实例。上面MainWindow的构造函数中的regionManager参数,就是Unity自动创建的。

参考:

RegionManager

代码中RegionManager的RegisterViewWithRegion方法将我们的视图(View)和区域适配器(Region)进行关联

RegionManager,它实现了IRegionManager接口。IRegionManager接口包含一个只读属性Regions,是Region的集合(这个集合是从xaml中获取的,也就是我们定义的那些),RegionManager的实例会使用他们,并将view注册给他们。

View Discovery和View Injection

在Prism中有两种方式来定义视图与Region之间的映射关系——View DiscoveryView Injection

上面的regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA));就是View Discovery

然后我们看一下View Injection

using Microsoft.Practices.Unity;using Prism.Regions;using System.Windows;namespace ViewInjection.Views{    ///     /// Interaction logic for MainWindow.xaml    ///     public partial class MainWindow : Window    {        IUnityContainer _container;        IRegionManager _regionManager;        public MainWindow(IUnityContainer container, IRegionManager regionManager)        {            InitializeComponent();            _container = container;            _regionManager = regionManager;        }        private void Button_Click(object sender, RoutedEventArgs e)        {            var view = _container.Resolve
(); IRegion region = _regionManager.Regions["ContentRegion"]; region.Add(view); } }}

他从_regionManager中获取Region,然后使用IRegion.Add(View)的方式来向已有的Region中添加View。

视图的激活与取消激活

private void Button_Click(object sender, RoutedEventArgs e)        {            //activate view a            _region.Activate(_viewA);        }        private void Button_Click_1(object sender, RoutedEventArgs e)        {            //deactivate view a            _region.Deactivate(_viewA);        }

转载地址:http://yxlia.baihongyu.com/

你可能感兴趣的文章
8分钟学会使用AutoMapper
查看>>
使用weka训练一个分类器
查看>>
C#根据WSDL文件生成WebService服务端代码
查看>>
[FJOI2018]领导集团问题
查看>>
thinkphp用ajax遇到的坑——ajax请求没有反应
查看>>
Microsoft Visual Studio 中出现 Windows has triggered a breakpoint in xxx.exe的一个解决方案
查看>>
非常直白的 js 闭包概念.<转载>
查看>>
shared_ptr模版推导的问题
查看>>
mac下用ruby安装sass && webstorm下给scss文件添加watch
查看>>
前端Demo常用库文件链接
查看>>
react create-react-app 跨域
查看>>
python html parse
查看>>
本机连接调试Erlang结点与rebar3编译
查看>>
web基础html元素制作web
查看>>
Codeforces 96C - Hockey
查看>>
生成树协议
查看>>
Web应用三种部署方式的优缺点
查看>>
python爬虫——绕开杂乱无章的代码和堵住请求的302异常(2)
查看>>
static易错点
查看>>
js获取当前日期(年月日格式)
查看>>