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

时间: 2024-11-06 05:48:32

GridRegionAdapter(slivelight)的相关文章

使用 IDEA 创建 Maven Web 项目 (异常)- Disconnected from the target VM, address: &#39;127.0.0.1:59770&#39;, transport: &#39;socket&#39;

运行环境: JDK 版本:1.8 Maven 版本:apache-maven-3.3.3 IDEA 版本:14 maven-jetty-plugin 配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${pro

在深圳有娃的家长必须要懂的社保少儿医保,不然亏大了!(收藏)

在深圳有娃的家长必须要懂的社保少儿医保,不然亏大了!(收藏) 转载2016-07-26 17:21:47 标签:深圳少儿医保社保医疗保险住院 在深圳工作或生活的家长们可能还有人不清楚,其实小孩子最大的基础保障福利就是少儿医保.如果以前没重视关注的,现在您看到这篇文章还来得及!少儿医保每年政府财政补贴384元,自己只需交200元左右,就可以享受门诊报销1000元,住院报销比例90%,最高报销额度达148万,大病门诊最高报销比例90%!如何享受?有哪些待遇?接下来就详细来做一个介绍: 少儿医保投保需

彻底解决_OBJC_CLASS_$_某文件名&quot;, referenced from:问题(转)

最近在使用静态库时,总是出现这个问题.下面总结一下我得解决方法: 1. .m文件没有导入   在Build Phases里的Compile Sources 中添加报错的文件 2. .framework文件没有导入静态库编译时往往需要一些库的支持,查看你是否有没有导入的库文件同样是在Build Phases里的Link Binary With Libraries中添加 3. 重复编译,可能你之前复制过两个地方,在这里添加过两次,删除时系统没有默认删除编译引用地址在Build Settings里搜索

爱奇艺、优酷、腾讯视频竞品分析报告2016(一)

1 背景 1.1 行业背景 1.1.1 移动端网民规模过半,使用时长份额超PC端 2016年1月22日,中国互联网络信息中心 (CNNIC)发布第37次<中国互联网络发展状况统计报告>,报告显示,网民的上网设备正在向手机端集中,手机成为拉动网民规模增长的主要因素.截至2015年12月,我国手机网民规模达6.20亿,有90.1%的网民通过手机上网. 图 1  2013Q1~2015Q3在线视频移动端和PC端有效使用时长份额对比 根据艾瑞网民行为监测系统iUserTracker及mUserTrac

Android 导航条效果实现(六) TabLayout+ViewPager+Fragment

TabLayout 一.继承结构 public class TabLayout extends HorizontalScrollView java.lang.Object ? android.view.View ? android.view.ViewGroup ? android.widget.FrameLayout ? android.widget.HorizontalScrollView ? android.support.design.widget.TabLayout 二.TabLayou

微信小程序——豆瓣电影——(2):小程序运行部署

Demo 预览 演示视频(流量预警 2.64MB) GitHub Repo 地址 仓库地址:https://github.com/zce/weapp-demo 使用步骤 将仓库克隆到本地: bash $ git clone https://github.com/zce/weapp-demo.git weapp-douban --depth 1 $ cd weapp-douban 打开微信Web开放者工具(注意:必须是0.9.092300版本) 必须是0.9.092300版本,之前的版本不能保证正

初识运维3--在虚拟机中安装Linux发行版系统(CentOS)的方法

在讲Linux系统发行版本的安装过程之前,先大略说明一下虚拟化. 虚拟化:将底层硬件资源抽象为用户更容易读懂和使用的逻辑抽象层的技术. 最早由IBM提出,现使用率较高的虚拟化软件平台有三类:VMware workstation.VirtualBOX.HyperV.在这里使用VMware workstation作为例子讲解说明安装过程. 虚拟化网络: 桥接模式:让物理机和虚拟机利用物理网络接口完成通信.虚拟机可以访问互联网. 仅主机模式:让虚拟机和物理机利用被虚拟出来的VMnet1网络接口完成通信

pythonの函数学习笔记(一)

函数是可以实现一些特定功能的小方法或小程序定义函数function的方法:def function_name(arg1,arg2[,...]): statement [return value]注意事项:1.def开头,代表定义函数,def和函数名中间要敲一个空格:2.返回值不是必须的,如果没有renturn语句,则默认返回值None:3.函数名必须以下划线或字母开头,可以包含任意字母.数字或下划线的组合,区分大小写且不能是保留字: py使用名称空间的概念存储对象,这个名称空间就是对象作用的区域

网络攻防第一次作业(201421450010)

姓名:陈书扬 学号:201421450010 指导教师:高见 1.虚拟机安装与调试 安装windows和linux(kali)两个虚拟机,均采用NAT网络模式,查看主机与两个虚拟机器的IP地址,并确保其连通性.同时为两个虚拟机做一个快照 windows虚拟机 Linux虚拟机 本地主机win10 两台主机都ping通 2.Windows基本命令 dir显示目录   cd 进入目录 Arp -a -d -s arp缓存 net share 查看计算机IPC$共享资源 netstat -ano网络链