GridRegionAdapter(slivelight)
原地址:http://www.xuebuyuan.com/68722.html
Prism学习之SilverlightWindowRegionAdapter[0评]
文章作者: healer
文章分类: 综合
发表时间: 2011-02-26 16:42:10
很多应用都需要多窗口支持,例如IM通讯工具,多窗口显示也能够提高的操作的灵活性,这个论据可以参考windows OS,但Silverlight中却没有内置提供多窗口显示支持,我们只能自己开发个“窗口”控件了,其实这样也好,省得还要去掉Windows窗口那些默认的显示效果;开发Silverlight或者WPF的人都喜欢用Prism来作为开发框架(Prism2.2发布了,全面支持Silverlight4 );本文讨论的是解决在Prism中使用多窗口的问题。
Prism是靠一堆统一管理的“Region”来动态显示模块界面的:先在需要显示界面的地方放个Region
<ItemsControl x:Name="MainRegion" Grid.Row="0" VerticalAlignment="Center" Regions:RegionManager.RegionName="MainRegion" Width="400" Height="300"/>
然后在模块文件(继承自IModule)中
this.regionManager.Regions["MainRegion"].Add(view);
这样就可以把指定的模块显示在指定的区域当中了。 Prism提供了三种类型的Region,分别是ContentControl、ItemsControl、Selector,偏偏没有用来显示“多窗口”的,我就找啊找啊,终于在这个项目http://compositewpfcontrib.codeplex.com/ 中找到了一个WPF的WindowRegionAdapter,所以我就依葫芦画瓢,给弄出个Silverlight的WindowRegionAdapter。
代码
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Practices.Composite.Regions; using Microsoft.Practices.Composite.Presentation.Regions; using System.Collections.Specialized;
namespace CompositeTest1.Common.Utilities { public class SLWindowRegionAdapter : RegionAdapterBase<Grid> { public SLWindowRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory) { }
protected override void Adapt(IRegion region, Grid regionTarget) { }
protected override IRegion CreateRegion() { return new SingleActiveRegion(); } protected override void AttachBehaviors(IRegion region, Grid regionTarget) { base.AttachBehaviors(region, regionTarget); WindowRegionBehavior behavior = new WindowRegionBehavior(regionTarget, region); behavior.Attach(); } } public class WindowRegionBehavior { private readonly WeakReference _ownerWeakReference; private readonly WeakReference _regionWeakReference;
public WindowRegionBehavior(Grid owner, IRegion region) { _ownerWeakReference = new WeakReference(owner); _regionWeakReference = new WeakReference(region); }
public void Attach() { IRegion region = _regionWeakReference.Target as IRegion; if (region != null) { region.Views.CollectionChanged += new NotifyCollectionChangedEventHandler(Views_CollectionChanged); region.ActiveViews.CollectionChanged += new NotifyCollectionChangedEventHandler(ActiveViews_CollectionChanged); } }
public void Detach() { IRegion region = _regionWeakReference.Target as IRegion; if (region != null) { region.Views.CollectionChanged -= Views_CollectionChanged; region.ActiveViews.CollectionChanged -= ActiveViews_CollectionChanged; } }
void window_LostFocus(object sender, RoutedEventArgs e) { IRegion region = _regionWeakReference.Target as IRegion; System.Windows.Controls.Window window = sender as System.Windows.Controls.Window; if (window != null && region != null) if (region.Views.Contains(window.Content)) region.Deactivate(window.Content); }
void window_GotFocus(object sender, RoutedEventArgs e) { IRegion region = _regionWeakReference.Target as IRegion; System.Windows.Controls.Window window = sender as System.Windows.Controls.Window; if (window != null && !region.ActiveViews.Contains(window.Content) && region.Views.Contains(window.Content)) region.Activate(window.Content); } private void window_Closed(object sender, EventArgs e) { System.Windows.Controls.Window window = sender as System.Windows.Controls.Window; IRegion region = _regionWeakReference.Target as IRegion;
if (window != null && region != null) if (region.Views.Contains(window.Content)) region.Remove(window.Content); Grid owner = _ownerWeakReference.Target as Grid; StackPanel spanel = owner.FindName("SLWindow") as StackPanel; if (spanel != null) { Button btn = spanel.FindName(window.Name.ToString().TrimEnd('M')) as Button; spanel.Children.Remove(btn); } }
private void ActiveViews_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { Grid owner = _ownerWeakReference.Target as Grid;
if (owner == null) { Detach(); return; }
if (e.Action == NotifyCollectionChangedAction.Add) { foreach (object view in e.NewItems) { System.Windows.Controls.Window window = GetContainerWindow(owner, view); if (window != null) { window.Focus(); } } } }
private void Views_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { Grid owner = _ownerWeakReference.Target as Grid; if (owner == null) { Detach(); return; } if (e.Action == NotifyCollectionChangedAction.Add) { foreach (object view in e.NewItems) { System.Windows.Controls.Window window = new System.Windows.Controls.Window(); window.GotFocus += new RoutedEventHandler(window_GotFocus); window.LostFocus += new RoutedEventHandler(window_LostFocus); window.Closed += new EventHandler(window_Closed); window.Content = view;
StackPanel spanel = owner.FindName("SLWindow") as StackPanel; if (spanel != null) { int index = spanel.Children.Count + 1; Button btn = new Button() { Name = "Window" + index, Content = "窗口" + index }; window.Name = "Window" + index+"M"; window.TitleContent = "窗口" + index; btn.Tag = window; btn.Click += new RoutedEventHandler(btn_Click); spanel.Children.Add(btn); } window.Container = owner; window.Show(DialogMode.Default); } } else if (e.Action == NotifyCollectionChangedAction.Remove) { foreach (object view in e.OldItems) { System.Windows.Controls.Window window = GetContainerWindow(owner, view);
if (window != null) window.Close(); } } }
void btn_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; System.Windows.Controls.Window window = btn.Tag as System.Windows.Controls.Window; if (window != null) { window.Visibility = window.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; } }
private System.Windows.Controls.Window GetContainerWindow(Grid owner, object view) { foreach (UIElement ui in owner.Children) { System.Windows.Controls.Window window = ui as System.Windows.Controls.Window; if (window != null && window.Content == view) return window; } return null; } } }
自定义的RegionAdapter要实现RegionAdapterBase<T>,这个T就是要承载Region的容器owner,我们的Window控件是需要一个Grid的容器的,所以就是RegionAdapterBase<Grid>,注意里面并没有直接实现Adapt方法,而是在重载AttachBehaviors方法中实现了对region.Views和region.ActiveViews的管理,并实现了窗口操作对View的影响,里面我还加了个类似于Windows任务栏的功能,当然实现的不完善,需要改进。
我们需要把自定义的RegionAdapter介绍给Prism中,让Prism认识他,通过在Bootstrapper中重载ConfigureRegionAdapterMappings方法实现
代码
protected override RegionAdapterMappings ConfigureRegionAdapterMappings() { RegionAdapterMappings regionAdapterMappings = Container.TryResolve<RegionAdapterMappings>(); IRegionBehaviorFactory regionBehaviorFactory = Container.TryResolve<IRegionBehaviorFactory>(); if (regionAdapterMappings != null && regionBehaviorFactory != null) { regionAdapterMappings.RegisterMapping(typeof(Grid), new SLWindowRegionAdapter(regionBehaviorFactory)); } return base.ConfigureRegionAdapterMappings(); }
然后在我需要承载弹出窗口的Grid更改成
<Grid x:Name="contentGrid" Grid.Row="1" Regions:RegionManager.RegionName="SLWindow">
然后在要呈现弹出窗口的地方
IRegion region = this.regionManager.Regions["SLWindow"]; if (region != null) region.Add(view);
搞定,看效果: 1、自动载入模块A,在模块A中弹出窗口显示模块A中的其他View

2、手动载入模块B,并在新的窗口中显示模块B的View

GridRegionAdapter(slivelight)的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ASP.NET Core 之 Identity 入门(一)
前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- Online Judge(OJ)搭建(第一版)
搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...
- 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑
阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...
- 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成
阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...
- 【.net 深呼吸】细说CodeDom(5):类型成员
前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...
- 【.net 深呼吸】细说CodeDom(4):类型定义
上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...
随机推荐
- 【转】IBM PowerVM虚拟化技术笔记
1. 从CPU虚拟化的角度, 分区(partition)可以分成两大类:Micro-partition和Dedicated-procesor.前者可以将物理处理器以0.01的 粒度分配给微分区,分区创 ...
- AGS Server 10.1 切图工具
在AGS Sever中很重要的功能就是地图缓存的制作,安装AGS Sever会在catalog中增加相关的工具箱,利用这些工具可以制作.删除.更新切片 一.Convert map server cac ...
- qt sql 模块有哪些类?
Class Description translate.google QSqlDatabase Handles a connection to a database 处理与数据库的连接 QSqlDri ...
- python多进程理论
什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): 你在一个时间段内有很多任务要做:python学习的任务,赚钱的任务,交女朋 ...
- orange安装文档
一.Orange简介 Orange是一个基于 OpenResty/Nginx 的 API Gateway,提供 API 及 “自定义规则” 的监控和管理,如访问统计.流量切分.AB 测试.API ...
- HTMLbutton控件中文字显示一直不居中
在写HTML时,发现HTML中button控件中文字显示一直不居中, 最后发现是在标签前出现了一个全角空格引起的. 在Emeditor中将不显示的字符(空格,全角空格,换行,制表符)设置为显示,就可以 ...
- windows安装pywin32
下载旧版 https://sourceforge.net/projects/pywin32/files/pywin32/ 下载新版 https://github.com/mhammond/pywin3 ...
- Hibernate学习---检索优化
Hibernate框架对检索进行了优化,前面我们将CURD的时候提到了load和get的区别,当时仅仅说了load为延迟加载,get为立即加载,当检索的记录为空的时候load报错(不是在执行load方 ...
- iOS 当公司有人向你提问,你该如何应对?
今天 因为iOS 开发的内部版本号耿耿于怀好久,释然后让我有了一个新想法:从前,能让我兴奋的点是解决一个有一个拗脑筋的问题,见大部分博客便知,都是技术方面的积累. 那么从今天起我决定让自己有个新起点, ...
- OC自动释放池autoreleasepool介绍
自动释放池的机制是:它使得应用在创建新对象时,系统能够有效地管理应用所使用的内存. @autoreleasepool { statements } 在创建新对象时,并且系统未启动ARC特性,那么在使用 ...