silverlight 学习笔记 (九):Prism与MVVM模式在silverlight中的应用

首先记录一个错误的解决办法,在使用Prism中在新增的Module中添加

Microsoft.Practices.Prism.MefExtensions的引用时需要注意将其“复制本地”改为false,否则会报以下错误:

An exception occurred while initializing module 'Module1'.
    - The exception message was: 撰写保持不变。由于以下错误,更改被拒绝: 撰写生成多个撰写错误,具有 15 个根本原因。下面提供了根本原因。 有关详细信息,请检查 CompositionException.Errors 属性

 回到正题,在silverlight中最常见得开发模式是MVVM+Prism+WCF RIA,通过前面的学习已基本账务了MVVM架构,至于WCF RIA需要学习的是EF以及我们需要灵活掌握异步开发模式。下面以实例说明一个简单的MVVM+Prism的架构。

首先理下思路:

1、利用前面学习的知识建立Bootstrapper ,并建立加载Shell,在Shell中布局Region

2、在Bootstrapper中重载CreateModuleCatalog方法,确定Module加载。

3、创建Module(刚学silverlight时习惯建立silverlight类库,而类库是无法形成xap),新建module的加载类,注意在该加载类中的属性标示名称需要和我们前面定义加载的xaml配置文件的module名称一致

[ModuleExport("Module1"typeof(Module1))]

4、在新的Module中新增View,ViewModel,在View中建立与ViewModel绑定关系

5、在Module加载类的初始化接口函数中指定Module初始加载的视图到指定的Region中

6、再次以代码验证上节说介绍的有关Export,Import,这将会在View、ViewModel中应用,同时需要掌握有关于如何灵活的将View注册到对应的Region中

到此基本上可以利用Prism对模块进行动态加载,同时如果将View注入到对应的Region中,而至于MVVM与原先的模式没有太多变化,只是更多的用到了MEF注入。下面需要研究思考的是关于Module之间如果通信的问题了,可以好好考虑学习下利用IEventAggregator 来实现模块间事件的订阅与发布,似乎有点类似于MVVM中的Messager了。

在基本理清了思路后,接下来做些简单的代码说明

1、Bootstrapper类

 

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.Prism.MefExtensions;
using System.ComponentModel.Composition.Hosting;

namespace Prism.MVVM.Test
{
     ///   <summary>
    
///  将MefExtensions的引用复制模式修改为false
    
///  很重要
    
///   </summary>
     public  class Bootstrapper:MefBootstrapper
    {
         ///   <summary>
        
///  创建Shell,从Container中获取注入的Shell实例
        
///   </summary>
        
///   <returns></returns>
         protected  override DependencyObject CreateShell()
        {
             return  this.Container.GetExportedValue<Shell>();
        }
         ///   <summary>
        
///  初始化Shell,设置启动界面为ShellView
        
///   </summary>
         protected  override  void InitializeShell()
        {
             base.InitializeShell();
            App.Current.RootVisual = (UIElement) this.Shell;
        }

         ///   <summary>
        
///  将自身添加到目录中,很重要,否则系统启动会报错
        
///   </summary>
         protected  override  void ConfigureAggregateCatalog()
        {
             base.ConfigureAggregateCatalog();
             this.AggregateCatalog.Catalogs.Add( new AssemblyCatalog( this.GetType().Assembly));
            
        }
         ///   <summary>
        
///  可建立xaml文件配置加载模块
        
///   </summary>
         protected  override Microsoft.Practices.Prism.Modularity.IModuleCatalog CreateModuleCatalog()
        {
             return
                Microsoft.Practices.Prism.Modularity.ModuleCatalog.CreateFromXaml( new Uri( " /Prism.MVVM.Test;component/ModulesCatalog.xaml ",
                                                                                          UriKind.Relative));

        }

         protected  override CompositionContainer CreateContainer()
        {
             var container =  base.CreateContainer();
            CompositionHost.Initialize(container);
             return container;
        }
       
        

    }
}

2、Shell布局,在该布局中主要用了ControlControl,如配合使用telerik下的RadTransitionControl 将会有更好的动画效果展现

<UserControl x:Class= " Prism.MVVM.Test.Shell "
    xmlns= " http://schemas.microsoft.com/winfx/2006/xaml/presentation "
    xmlns:x= " http://schemas.microsoft.com/winfx/2006/xaml "
    xmlns:d= " http://schemas.microsoft.com/expression/blend/2008 "
    xmlns:mc= " http://schemas.openxmlformats.org/markup-compatibility/2006 "
    xmlns:prism= " clr-namespace:Microsoft.Practices.Prism.Regions;assembly=Microsoft.Practices.Prism "
    mc:Ignorable= " d "
    d:DesignHeight= " 300 " d:DesignWidth= " 400 ">

    <Grid x:Name= " LayoutRoot " Background= " #FFE2E25E ">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width= " 104* " />
            <ColumnDefinition Width= " 296* " />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height= " 62* " />
            <RowDefinition Height= " 238* " />
        </Grid.RowDefinitions>
        <Border BorderBrush= " Silver " BorderThickness= " 1 " Grid.ColumnSpan= " 2 " HorizontalAlignment= " Stretch " Margin= " 0 " Name= " border1 " VerticalAlignment= " Stretch " Background= " #FF4848B9 ">
            <ContentControl Name= " contentControl1 " prism:RegionManager.RegionName= " MainTitleRegion " />
        </Border>
        <Border BorderBrush= " Silver " BorderThickness= " 1 " Grid.Column= " 1 " Grid.Row= " 1 " HorizontalAlignment= " Stretch " Margin= " 0 " Name= " border2 " VerticalAlignment= " Stretch " CornerRadius= " 5 " Background= " #FF0B418F ">
            <ContentControl Name= " contentControl3 " prism:RegionManager.RegionName= " MainContentRegion " />
        </Border>
        <Border BorderBrush= " Silver " BorderThickness= " 1 " Grid.Row= " 1 " HorizontalAlignment= " Stretch " Name= " border3 " VerticalAlignment= " Stretch " CornerRadius= " 5 " Background= " #FF0B418F ">
            <ContentControl Name= " contentControl2 " prism:RegionManager.RegionName= " MainNavRegion " />
        </Border>

    </Grid>
</UserControl>

 3、module加载

ExpandedBlockStart.gif View Code
 1  using System;
 2  using System.Net;
 3  using System.Windows;
 4  using System.Windows.Controls;
 5  using System.Windows.Documents;
 6  using System.Windows.Ink;
 7  using System.Windows.Input;
 8  using System.Windows.Media;
 9  using System.Windows.Media.Animation;
10  using System.Windows.Shapes;
11  using Microsoft.Practices.Prism.Modularity;
12  using Microsoft.Practices.Prism.MefExtensions.Modularity;
13  using Microsoft.Practices.Prism.Regions;
14  using System.ComponentModel.Composition;
15  using Module1.View;
16  using Microsoft.Practices.ServiceLocation;
17 
18  namespace Module1
19 {
20     [ModuleExport( " Module1 "typeof(Module1))]
21      public  class Module1 : IModule, IPartImportsSatisfiedNotification 
22     {
23         [Import]
24          public IRegionManager regionManager;
25          public  void Initialize()
26         {
27              var titleview = ServiceLocator.Current.GetInstance( typeof(TitleView),  " TitleView ");
28              var navView = ServiceLocator.Current.GetInstance( typeof(NavView),  " NavView ");
29              this.regionManager.RegisterViewWithRegion(RegionNames.MainTitleRegion, () => {  return ServiceLocator.Current.GetInstance( typeof(TitleView),  " TitleView "); });
30              if ( this.regionManager.Regions[RegionNames.MainNavRegion].GetView( " NavView ")== null)
31                  this.regionManager.Regions[RegionNames.MainNavRegion].Add(navView);
32              this.regionManager.RequestNavigate(RegionNames.MainContentRegion,  " DefaultContentView ");
33         }
34 
35          public  void OnImportsSatisfied()
36         {
37              // throw new NotImplementedException();
38          }
39     }
40 }

4、创建View,ViewModel

 

ExpandedBlockStart.gif View Code
 1 [Export( " TitleView ")]
 2      public  partial  class TitleView : UserControl
 3     {
 4          public TitleView()
 5         {
 6             InitializeComponent();
 7         }
 8         [Import( " TitleViewModel ")]
 9          public TitleViewModel ViewModel {  get {  return  this.DataContext  as TitleViewModel; }  set {  this.DataContext = value; } }
10     }

 

ExpandedBlockStart.gif View Code
 1  using System;
 2  using System.Net;
 3  using System.Windows;
 4  using System.Windows.Controls;
 5  using System.Windows.Documents;
 6  using System.Windows.Ink;
 7  using System.Windows.Input;
 8  using System.Windows.Media;
 9  using System.Windows.Media.Animation;
10  using System.Windows.Shapes;
11  using System.ComponentModel.Composition;
12 
13  namespace Module1.ViewModel
14 {
15     [Export( " TitleViewModel ")]
16      public  class TitleViewModel
17     {
18          public  string ProjectName {  get {  return  " 我的测试项目 "; } }
19     }
20 }

 

 

转载于:https://www.cnblogs.com/oldkingsir/archive/2012/02/25/2367330.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值