原地址: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)的更多相关文章

  1. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  2. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  3. ASP.NET Core 之 Identity 入门(一)

    前言 在 ASP.NET Core 中,仍然沿用了 ASP.NET里面的 Identity 组件库,负责对用户的身份进行认证,总体来说的话,没有MVC 5 里面那么复杂,因为在MVC 5里面引入了OW ...

  4. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  5. Online Judge(OJ)搭建(第一版)

    搭建 OJ 需要的知识(重要性排序): Java SE(Basic Knowledge, String, FileWriter, JavaCompiler, URLClassLoader, Secur ...

  6. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  7. 如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成

    阅读目录 前言 建模 实现 结语 一.前言 前面几篇已经实现了一个基本的购买+售价计算的过程,这次再让售价丰满一些,增加一个会员价的概念.会员价在现在的主流电商中,是一个不大常见的模式,其带来的问题是 ...

  8. 【.net 深呼吸】细说CodeDom(5):类型成员

    前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...

  9. 【.net 深呼吸】细说CodeDom(4):类型定义

    上一篇文章中说了命名空间,你猜猜接下来该说啥.是了,命名空间下面就是类型,知道了如何生成命名空间的定义代码,之后就该学会如何声明类型了. CLR的类型通常有这么几种:类.接口.结构.枚举.委托.是这么 ...

随机推荐

  1. https nginx openssl 自签名

    公私钥:公钥可以唯一解密私钥加密过的数据,反之亦然.以下用P指代公钥,V指代私钥.SSL过程:需要两对公私钥(P1,V1),(P2,V2),假设通信双方是A和B,B是服务器,A要确认和它通信的是B:A ...

  2. 任务04——对四则运算小程序的进一步改进,并学习 Git 中 Branch 的用法

    https://github.com/jinxiaohang/Operation/tree/test01 对于任务2的代码进行优化修改感觉很麻烦,所以直接选择重写代码完成任务四, 任务四很早就发布了, ...

  3. CalendarUtil 日期操作工具类

    版权声明:本文为博主原创文章,未经博主允许不得转载. [java] view plain copy import java.util.Calendar; import java.text.DateFo ...

  4. 【转】Linux系统上安装MySQL 5.5 rpm

    1.准备工作 从MySQL官网上分别下载mysql服务器端于客户端包. 如: MySQL-server-5.5.15-1.linux2.6.x86_64.rpm和MySQL-client-5.5.15 ...

  5. Linux学习笔记(2)linux系统信息与进程相关命令

    man 获得命令的帮助手册,如man cp:按q键退出 su 切换用户,如su - root; '-'表示改变用户的环境变量 who 显示系统中登录的用户 w 显示登录用户的详细信息 last 查看最 ...

  6. 011-git-将tag推送到远端

    1.将tag推送到远端 在使用TortoiseGit过程中,push推送过程中,选择include tag,远端就有次分支.

  7. microsoft cl.exe 编译器

    cl.exe是visual stdio 内置的编译器,visual stdio包含各种功能,有些功能可能这辈子都用不到,体积庞大,如果是 开发比较大或者有图形的项目,vs是首选.更多情况时更喜欢使用文 ...

  8. 安装和使用jupyter

    安装 pip install jupyter 使用 jupyter notebook

  9. 【WEB】前段优化

    模块化管理: sea.js, require.js 压缩:r.js gulp.js, grunt.js 加速:cdn

  10. 剑指offer 面试38题

    面试38题: 题:字符串的排列 题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,ca ...