ToB企服应用市场:ToB评测及商务社交产业平台

标题: WPF开发框架Caliburn.Micro详解 [打印本页]

作者: 海哥    时间: 2024-12-16 11:08
标题: WPF开发框架Caliburn.Micro详解
随着项目的发展,功能越来越复杂,解耦已经是每一个项目都会遇到的题目。在WPF开发中,MVVM开发模式是主要就是为了将UI页面和业务逻辑分离开来,从而便于测试,提升开发服从。当前比较流行的MVVM框架,主要有Prism,Community.Toolkit,以及今天介绍的Caliburn.Micro。而Caliburn.Micro框架是一款小巧但非常给力的框架,使用此框架,可以非常快速的构建WPF程序来支持MVVM开发模型。本文仅供学习分享使用,如有不敷之处,还请指正。

Caliburn.Micro框架安装

起首打开VisualStudio开发工具,在WPF应用程序中,在项目或办理方案右键打开Nuget包管理器窗口,然后搜刮Caliburn.Micro,然后进行安装即可。如下图所示: 

Caliburn.Micro基础配置

在新创建的WPF应用程序中,基础配置如下:
删除默认文件:WPF项目创建成功后,要使用Caliburn.Micro库,可以删除项目中默认创建的启动窗口MainWindow.xaml,并删除App.xaml中默认启动项StartupUri。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application>
复制代码
创建默认ViewModel,并定名为ShellViewModel,以及ShellView.xaml。ShellViewModel继承自Conductor或者PropertyChangedBase表示此类具备了属性关照功能。 ShellViewModel代码如下所示:
  1. public class ShellViewModel : PropertyChangedBase
  2. {
  3.         string name;
  4.         public string Name
  5.         {
  6.                 get { return name; }
  7.                 set
  8.                 {
  9.                         name = value;
  10.                         NotifyOfPropertyChange(() => Name);
  11.                         NotifyOfPropertyChange(() => CanSayHello);
  12.                 }
  13.         }
  14.         public bool CanSayHello
  15.         {
  16.                 get { return !string.IsNullOrWhiteSpace(Name); }
  17.         }
  18.         public void SayHello()
  19.         {
  20.                 MessageBox.Show(string.Format("Hello {0}!", Name)); //Don't do this in real life :)
  21.         }
  22. }
复制代码
创建Bootstrapper类,此类是配置Caliburn框架的焦点,告诉程序改怎样启动应用程序。在此类中重写OnStartUp函数,并在此方法中通过DisplayRootViewForAsync指定程序启动项ShellViewModel。同样也可以通过设置启动页面视图的方式Application.RootVisual = new ShellView();来启动程序。
  1. public class Bootstrapper : BootstrapperBase
  2. {
  3.         public Bootstrapper()
  4.         {
  5.                 Initialize();
  6.         }
  7.         protected override async void OnStartup(object sender, StartupEventArgs e)
  8.         {
  9.                 await DisplayRootViewForAsync(typeof(ShellViewModel));
  10.         }
  11. }
复制代码
在App.xaml中界说Bootstrapper对象,作为资源引用,而剩下的工作将由Bootstrapper完成。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application><Application x:
  10.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  11.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  12.              xmlns:local="clr-namespace:DemoCaliburn">
  13.     <Application.Resources>
  14.         <ResourceDictionary>
  15.         </ResourceDictionary>
  16.     </Application.Resources>
  17. </Application><Application x:
  18.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  19.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  20.              xmlns:local="clr-namespace:DemoCaliburn">
  21.     <Application.Resources>
  22.         <ResourceDictionary>
  23.         </ResourceDictionary>
  24.     </Application.Resources>
  25. </Application><Application x:
  26.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  27.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  28.              xmlns:local="clr-namespace:DemoCaliburn">
  29.     <Application.Resources>
  30.         <ResourceDictionary>
  31.         </ResourceDictionary>
  32.     </Application.Resources>
  33. </Application>   
复制代码
Caliburn.Micro采用了一种简单的定名约定【将ViewModel去掉Model就是View的名称,如:ShellViewModel对应的视图为ShellView】来为ViewModel指定需要渲染的View。 同样Caliburn.Micro框架还会根据元素的x:Name属性,在ViewModel中为控件匹配对应的属性或方法绑定。 
配置Bootstrapper,Bootstrapper类可以用于配置Caliburn.Micro的基础配置,如配置Ioc容器,变乱聚合器,注入实例等 在Bootstrapper中,通过SimpleContainer注入和获取实例,以及Build实例 通过重写Configure方法,将要注入的对象注入到容器中。获取的时候通过类型和key进行获取 。
  1. public class Bootstrapper:BootstrapperBase
  2. {
  3.         private readonly SimpleContainer _container = new SimpleContainer();
  4.         public Bootstrapper()
  5.         {
  6.                 Initialize();
  7.                 LogManager.GetLog = type => new DebugLog(type);//增加日志
  8.         }
  9.         protected override async void OnStartup(object sender, StartupEventArgs e)
  10.         {
  11.                 await DisplayRootViewForAsync(typeof(ShellViewModel));
  12.         }
  13.         protected override void Configure()
  14.         {
  15.                 _container.Instance(_container);
  16.                 _container.Singleton<IWindowManager, WindowManager>()
  17. .Singleton<IEventAggregator, EventAggregator>();
  18.                 foreach (var assembly in SelectAssemblies())
  19.                 {
  20.                         assembly.GetTypes()
  21.                    .Where(type => type.IsClass)
  22.                    .Where(type => type.Name.EndsWith("ViewModel"))
  23.                    .ToList()
  24.                    .ForEach(viewModelType => _container.RegisterPerRequest(
  25.                            viewModelType, viewModelType.ToString(), viewModelType));
  26.                 }
  27.         }
  28.         protected override IEnumerable<Assembly> SelectAssemblies()
  29.         {
  30.                 // https://www.jerriepelser.com/blog/split-views-and-viewmodels-in-caliburn-micro/
  31.                 var assemblies = base.SelectAssemblies().ToList();
  32.                 //assemblies.Add(typeof(LoggingViewModel).GetTypeInfo().Assembly);
  33.                 return assemblies;
  34.         }
  35.         protected override object GetInstance(Type service, string key)
  36.         {
  37.                 return _container.GetInstance(service, key);
  38.         }
  39.         protected override IEnumerable<object> GetAllInstances(Type service)
  40.         {
  41.                 return _container.GetAllInstances(service);
  42.         }
  43.         protected override void BuildUp(object instance)
  44.         {
  45.                 _container.BuildUp(instance);
  46.         }
  47. }
复制代码
Action

在Caliburn.Micro中,Action通过Microsoft.Xaml.Behaviors的变乱触发机制来实现。也就是说你可以使用任何Microsoft.Xaml.Behaviors.TriggerBase的派生类,来触发ActionMessage。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application><Application x:
  10.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  11.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  12.              xmlns:local="clr-namespace:DemoCaliburn">
  13.     <Application.Resources>
  14.         <ResourceDictionary>
  15.         </ResourceDictionary>
  16.     </Application.Resources>
  17. </Application><Application x:
  18.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  19.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  20.              xmlns:local="clr-namespace:DemoCaliburn">
  21.     <Application.Resources>
  22.         <ResourceDictionary>
  23.         </ResourceDictionary>
  24.     </Application.Resources>
  25. </Application><Application x:
  26.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  27.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  28.              xmlns:local="clr-namespace:DemoCaliburn">
  29.     <Application.Resources>
  30.         <ResourceDictionary>
  31.         </ResourceDictionary>
  32.     </Application.Resources>
  33. </Application><Window x:
  34.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  35.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  36.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  37.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  38.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  39.         mc:Ignorable="d"
  40.         Title="ShellView" Height="450" Width="800">
  41.     <Grid>
  42.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  43.     </Grid>
  44. </Window>     
复制代码
ActionMessage会沿着可视化树通过Bubbles的方式一层一层向上探求可以或许处置惩罚的Target实例。如果探求到Target,则响应变乱,如果没有,则抛出异常。
默认情况下,任何通过ViewModelBinder来进行绑定的将会自动设置为Target对象,当然也可以通过附加属性Action.Target来为Action设置目标实例。
Message.Attach,此属性有一组简单的分析程序提供支持,它通过解析文本输入的方式来提供完整的ActionMessage。默认情况下,Message.Attach 声明未指定应由哪个变乱发送消息。如果省略该变乱,解析器将使用 ConventionManager 来确定要用于触发器的默认变乱。对于 Button,它是 Click。 
  1. [/code]设置Action Target的几种方式:
  2. [list]
  3. [*]Action.Target,通过设置Action.Target和DataContext属性来指定实例,以字符串的形式设置,Caliburn.Micro框架会自动通过Ioc容器进行解析。
  4. [*]Action.TargetWithoutContext,仅设置Action.Target来指定实例,同样以字符串的形式设置,Caliburn.Micro框架会自动通过Ioc容器进行解析。
  5. [*]Bind.Model,View-First方式,设置Action.Target和DataContext来指定实例,同样以字符串的形式设置,Caliburn.Micro框架会自动通过Ioc容器进行解析。
  6. [*]Bind.ModelWithoutContext,View-First方式,设置Action.Target来指定实例。
  7. [*]View.Model,ViewModel-First 优先的方式,为ViewModel指定对应的视图  
  8. [/list]在ViewModel中,假如我们的Action需要一个参数name。
  9. [code]public class ShellViewModel : IShell
  10. {
  11.     public bool CanSayHello(string name)
  12.     {
  13.         return !string.IsNullOrWhiteSpace(name);
  14.     }
  15.     public void SayHello(string name)
  16.     {
  17.         MessageBox.Show(string.Format("Hello {0}!", name));
  18.     }
  19. }
复制代码
在UI视图中,可以通过Caliburn框架中的Parameter对象为ActionMessage指定参数。 Parameter对象的Value属性是依赖属性,可以进行Binding具备变更关照的属性。 可以为ActionMessage指定多个参数。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application><Application x:
  10.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  11.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  12.              xmlns:local="clr-namespace:DemoCaliburn">
  13.     <Application.Resources>
  14.         <ResourceDictionary>
  15.         </ResourceDictionary>
  16.     </Application.Resources>
  17. </Application><Application x:
  18.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  19.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  20.              xmlns:local="clr-namespace:DemoCaliburn">
  21.     <Application.Resources>
  22.         <ResourceDictionary>
  23.         </ResourceDictionary>
  24.     </Application.Resources>
  25. </Application><Application x:
  26.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  27.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  28.              xmlns:local="clr-namespace:DemoCaliburn">
  29.     <Application.Resources>
  30.         <ResourceDictionary>
  31.         </ResourceDictionary>
  32.     </Application.Resources>
  33. </Application><Application x:
  34.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  35.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  36.              xmlns:local="clr-namespace:DemoCaliburn">
  37.     <Application.Resources>
  38.         <ResourceDictionary>
  39.         </ResourceDictionary>
  40.     </Application.Resources>
  41. </Application><Application x:
  42.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  43.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  44.              xmlns:local="clr-namespace:DemoCaliburn">
  45.     <Application.Resources>
  46.         <ResourceDictionary>
  47.         </ResourceDictionary>
  48.     </Application.Resources>
  49. </Application>         
复制代码
通过上述方式,还可以有其他几种方式来为ActionMessage指定参数:
View-First

Caliburn.Micro默认采用ViewModel优先的方式加载程序,通过也可以通过View-First的方式启动。 在Bootstrapper的OnStartup方法中,通过Application.RootVisual = new ShellView();指定要启动的视图。
  1. protected override void OnStartup(object sender, StartupEventArgs e)
  2. {
  3.         Application.RootVisual = new ShellView();
  4. }
复制代码
将ViewModel设置要导出的名称Key。
  1. [Export("Shell", typeof(IShell))]
  2. public class ShellViewModel : PropertyChangedBase, IShell
  3. {
  4.     //same as before
  5. }
复制代码
 修改视图,并通过附加属性Bind.Model为视图设置对应的ViewModel。它将通过Key从Ioc容器中解析对应的ViewModel。 
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application>
复制代码
常见的接口和基类

由于一些功能经常用到,Caliburn.Micro封装成了一些基类,如下所示:
上述这些意味着在ViewModel中,可以继承自PropertyChangedBase 或者 Screen。通俗点讲,当需要激活功能的时候用Screen,其他的则可以使用PropertyChangedBase。 
同样当使用了生命周期,则需要脚色来管理它,而Conductor,在Caliburn.Micro中,通过实现IConductor接口来实现,此接口提供了如下方法:
作为一个Presentation的框架,各个UI部件(Widget或者叫Pad)的管理是必不可少的。Screen就是用来表示UI部件的,它界说了一些列UI部件的生命期管理函数,比如Activated,DeActivated,TryClose等,并且可以通过GetView可以得到对应的View对象。因为Screen实现了很多功能,所以个人建议全部ViewModel都继承自Screen。Conductor可以用来管理Screen,不同的Screen可以用一个Conductor来管理,Conductor也使用了计谋模式答应更改对Screen的处置惩罚;继承Conductor的ViewModel可以调用ActiveItem等方法管理继承自Screen的ViewModel;Conductor本身也是个Screen,因为Conductor也继承了Screen类。相干继承关系如下:
从Screen派生和窗口管理有关的类的继承关系(可以查看了Window Manager、Screen和Conductor后再看):
Caliburn.Micro中的约定

Caliburn.Micro的主要功能之一是它可以或许通过一系列的约定来消除对样板代码的需要,默认约定处于ON状态,如果不需要可以关闭。
ViewModel和View的约定,在 ViewModel-First 中,我们有一个现有的 ViewModel,需要将其渲染到屏幕上。为此,CM 使用简单的定名模式来查找它应绑定到 ViewModel 并显示的 UI视图。这种定名模式就是ViewModel去掉Model就是对应的视图名称,如:CustomerViewModel默认情况下,对应的视图为CustomerView。这是通过ViewLocator.LocateForModelType 实现的。
尽管 Caliburn.Micro 更喜欢 ViewModel-First 开发,但偶然您可能盼望采用 View-First 方法。在View-First模式下,我们采用ViewModelLocator.LocateForViewType来实现定名模式。这种定名模式就是将视图中的View替换成ViewModel,如果找到匹配项,则从Ioc容器中解析它。
ViewModelLocator.LocateForView起首检查View实例的DataContext,查看之前是否缓存或自界说创建了ViewModel,如果为空,只有这样才会调用LocateForViewType,去查找对应的ViewModel。 ViewModelBinder视图模型,当我们将您的 View 和 ViewModel 绑定在一起时,无论您使用的是 ViewModel-First 还是 View-First 方法,都会调用 ViewModelBinder.Bind 方法。此方法将 View 的 Action.Target 设置为 ViewModel,并相应地将 DataContext 设置为相同的值。它还会检查您的 ViewModel 是否实现 IViewAware,如果是,则将 View 通报给您的 ViewModel。ViewModelBinder 做的末了一件紧张事情是确定它是否需要创建任何常规属性绑定或操作。为此,它会在界面中搜刮绑定/操作的候选元素列表,并将其与 ViewModel 的属性和方法进行比较。找到匹配项后,它会代表您创建绑定或操作。
如果不喜欢 ViewModelBinder 的行为,,它遵循与上述框架服务相同的模式。它有几个 Func,您可以用本身的实现替换,比方 Bind、BindActions 和 BindProperties。如果想要关闭,请将 ViewModelBinder.ApplyConventionsByDefault 设置为 false。如果要逐个视图启用它,可以在 View 上将 View.ApplyConventions 附加属性设置为 true。 


如果你仔细检查,你会发现上面的两个约定之间存在渺小的差异。只需将“ViewModel”添加到以“Page”为后缀的名称中,即可生成其 ViewModel 的名称。但是,只有 “Model” 会添加到以 “View” 为后缀的名称中,以生成其配套 ViewModel 的名称。这种差异主要源于将某项内容定名为“MainViewViewModel”而不是“MainPageViewModel”的语义尴尬。因此,从“View”后缀的 View 名称派生的 ViewModel 的定名约定通过将 ViewModel 定名为“MainViewModel”来避免冗余。 
定名空间约定,Caliburn.Micro建议ViewModel和View在同一个定名空间中。 也可以根据不同的功能分类,将视图和ViewModel组织在不同的文件夹中。 


变乱聚合器

Caliburn.Micro默认提供了一个EventAggregator,它提供了一种以松散的方式将对象从一个实体发布到另一个实体的能力。Event Aggregator 实际上是一种设计模式,它的实现可能因框架而异。要正确的使用EventAggregator,它必须作为应用程序级别服务存在,通常是将它创建为单例来实现,建议通用Ioc容器进行注入和获取变乱聚合器。
在Bootstrapper中的Configure方法中,注入变乱聚合器对象。
发布变乱,获取变乱聚合器对象后,就可以调用,可以用变乱聚合器发送任何对象。
  1. public class FooViewModel {
  2.         private readonly IEventAggregator _eventAggregator;
  3.         public FooViewModel(IEventAggregator eventAggregator) {
  4.             _eventAggregator = eventAggregator;
  5.             _eventAggregator.PublishOnUIThread(new object());
  6.             _eventAggregator.PublishOnUIThread("Hello World");
  7.             _eventAggregator.PublishOnUIThread(22);
  8.         }
  9. }
复制代码
订阅,任何实体都可以通过 Subscribe 方法将自身提供给 EventAggregator 来订阅任何 Event。
  1. public class FooViewModel : IHandle<object> {
  2.     private readonly IEventAggregator _eventAggregator;
  3.     public FooViewModel(IEventAggregator eventAggregator) {
  4.         _eventAggregator = eventAggregator;
  5.         _eventAggregator.Subscribe(this);
  6.     }
  7.     public void Handle(object message) {
  8.         // Handle the message here.
  9.     }
  10. }
复制代码
为了使此功能易于使用,我们提供了一个特别接口 (IHandle),用于将订阅者标记为对给定类型的 Event 感爱好。
请注意,通过实现上面的接口,如果 T 是您指定感爱好的消息类型,您将被迫实现方法 Handle(T message)。此方法是在发布匹配的 Event 类型时调用的。 
单个实体想要侦听多个变乱类型的情况并不少见。由于我们使用泛型,这就像向订阅者添加第二个 IHandle 接口一样简单。请注意,Handle 方法现在使用新的 Event 类型重载。
  1. public class FooViewModel : IHandle<object> {
  2.     private readonly IEventAggregator _eventAggregator;
  3.     public FooViewModel(IEventAggregator eventAggregator) {
  4.         _eventAggregator = eventAggregator;
  5.         _eventAggregator.Subscribe(this);
  6.     }
  7.     public void Handle(object message){
  8.         if (_eventAggregator.HandlerExistsFor(typeof(SpecialMessageEvent))){
  9.             _eventAggregator.PublishOnUIThread(new SpecialEventMessage(message));
  10.         }
  11.     }
  12. }
复制代码
Caliburn.Micro 的 EventAggregator 支持多态性。选择要调用的处置惩罚程序时,EventAggregator 将触发任何 Event 类型的处置惩罚程序,该处置惩罚程序可从正在发送的 Event 中分配。这带来了很大的灵活性,并有助于重用。
  1. public class FooViewModel : IHandle<string>, IHandle<bool> {
  2.     private readonly IEventAggregator _eventAggregator;
  3.     public FooViewModel(IEventAggregator eventAggregator) {
  4.         _eventAggregator = eventAggregator;
  5.         _eventAggregator.Subscribe(this);
  6.     }
  7.     public void Handle(string message) {
  8.         // Handle the message here.
  9.     }
  10.     public void Handle(bool message) {
  11.         // Handle the message here.
  12.     }
  13. }
复制代码
在下面的示例中,由于 String 派生自 System.Object,因此在发布 String 消息时,将调用这两个处置惩罚程序。
  1. public class FooViewModel : IHandle<object>, IHandle<string> {
  2.     private readonly IEventAggregator _eventAggregator;
  3.     public FooViewModel(IEventAggregator eventAggregator) {
  4.         _eventAggregator = eventAggregator;
  5.         _eventAggregator.Subscribe(this);
  6.         _eventAggregator.PublishOnUIThread("Hello");
  7.     }
  8.     public void Handle(object message) {
  9.         // This will be called
  10.     }
  11.     public void Handle(string message) {
  12.         // This also
  13.     }
  14. }
复制代码
查询变乱处置惩罚程序,Caliburn.Micro提供了一种机制来查询 EventAggregator 以查看给定的 Event 类型是否具有任那里置惩罚程序,这在假定至少存在一个处置惩罚程序的特定情况下非常有用。 
Ioc容器

Caliburn.Micro 预先设置了一个名为 SimpleContainer 的依赖注入容器。依赖注入实际上是一种模式,通常使用容器元素而不是手动服务映射。
在向 SimpleContainer 添加任何服务绑定之前,请务必记着,容器本身必须向 Caliburn.Micro 注册,框架才能使用上述绑定。此过程会将 SimpleContainer 注入 IoC,这是 Caliburn.Micro 的内置 Service Locator。
 在大多数情况下,构造函数注入是最好的选择,因为它使服务要求明确,但是属性注入有很多用例。需要注意的是,属性注入仅适用于 Interface 类型。 
  1. public class ShellViewModel {
  2.     private readonly IWindowManager _windowManager;
  3.     public ShellViewModel(IWindowManager windowManager) {
  4.         _windowManager = windowManager;
  5.     }
  6. }
复制代码
通过容器获取单个服务。通过Ioc的Get方法可以获取服务,可以获取默认的服务,也可以通过指定的Key获取服务。
  1. //获取单个服务
  2. var windowManager = IoC.Get<IWindowManager>();
  3. var windowManager = IoC.Get<IWindowManager>("windowManager");
复制代码
获取服务列表,通过Ioc的GetAll方法,可以获取满意条件的服务列表,返回类型为 IEnumerable,此中T是哀求的服务类型。
  1. //获取服务列表
  2. var viewModelCollection = IoC.GetAll<IViewModel>();
  3. var viewModel = IoC.GetAll<IViewModel>().FirstOrDefault(vm => vm.GetType() == typeof(ShellViewModel));
复制代码
注入服务实例,通过Ioc的BuildUp方法,可以将实例对象注入到容器中。 
  1. //注入实例
  2. var viewModel = new LocallyCreatedViewModel();
  3. IoC.BuildUp(viewModel);
复制代码
MVVM简介

MVVM 代表 Model、View、View Model。根本思想是创建一个三层用户界面。它的主要用途是将 UI 的可视部分(表单、按钮和其他控件)尽可能与处置惩罚 UI 命令的逻辑分开。对于 WPF 应用程序,视图由 XAML 代码和代码隐藏表示,这实质上是用 C# 编写 XAML 代码的方法。此层不应实行任那里置惩罚。View Model 是功能性 UI 层,它接受来自 UI 的命令并处置惩罚这些命令。第三层是 Model,它保存数据模型。 比方,如果用户按下 View 中的按钮,则会向 View Model 发送一个命令,该命令将确定要做什么并实行该命令。在本教程的背面部分,您将看到更多内容。Model 应用于表示对象的 (自界说) 数据模型。 您可以将这三个层与程序逻辑 (功能层) 和数据访问层分开,这将将您的功能层与数据访问分开。 
如果您创建一个非常简单的应用程序,则可能不需要使用 MVVM。MVVM 将在您的应用程序上产生一些开销,您需要一些时间来学习怎样应用 MVVM。如果您想使用自动化测试,您很快就会发现通过 UI 进行测试很困难,并且由于 UI 通常会频繁更改,因此很难维护测试。在这种情况下,View Model 是一个更好的测试访问点。您可以使用常规的单元测试方法。 
您可以很好地开始使用 MVVM 原则,而无需使用 Caliburn.Micro。从第一天开始,将 Caliburn.Micro 用于新项目的工作量较少,但如果您已经使用 View-ViewModel 分离,则在许多情况下可以非常快速地迁移到 Caliburn.Micro。即使您尚未使用 Caliburn.Micro,也可以开始使用 Caliburn.Micro。在大多数情况下,它不会影响现有代码。您也不需要采用全部 Caliburn.Micro 功能。它是灵活的。 
MVVM应用

在Caliburn.Micro框架中,开始MVVM,主要步骤如下:

ShellView.xaml页面内容如下所示:
  1. <Window x:
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  7.         mc:Ignorable="d"
  8.         Title="ShellView" Height="450" Width="800">
  9.     <Grid>
  10.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  11.     </Grid>
  12. </Window>
复制代码
配置Bootstrapper,注意事项如下所示:
MVVM实例

创建模型,起首创建一个Category类,包含Id,Name,Description三个属性,并保存在Models文件夹。
  1. namespace DemoCaliburn.Models
  2. {
  3.     public class Category
  4.     {
  5.         public int Id { get; set; }
  6.         public string Name { get; set; }
  7.         public string Description { get; set; }
  8.     }
  9. }
复制代码
创建ViewModel,创建一个CategoryViewModel,存放在ViewModels文件夹,CategoryViewModel继承自Screen。 类型为BindableCollection CategoryList是全部类别列表,用于绑定UI视图的DataGrid 类型为Category SelectedCategory的表示列表选中项。 在属性CategoryName,CategoryDescription的set方法中增加了NotifyOfPropertyChange(nameof(CategoryName));语句来实现更改关照的功能。 重载了Screen的OnViewLoaded方法,此方法表示页面加载完成后调用。  增加了Edit(编辑)、Delete(删除)、Save (保存) 和 Clear(清除)。 
  1. namespace DemoCaliburn.ViewModels{    public class CategoryViewModel:Screen    {        private BindableCollection _categoryList = new BindableCollection();        public BindableCollection CategoryList        {            get            {<Window x:
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  7.         mc:Ignorable="d"
  8.         Title="ShellView" Height="450" Width="800">
  9.     <Grid>
  10.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  11.     </Grid>
  12. </Window>return _categoryList;            }            set            {<Window x:
  13.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  14.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  15.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  16.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  17.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  18.         mc:Ignorable="d"
  19.         Title="ShellView" Height="450" Width="800">
  20.     <Grid>
  21.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  22.     </Grid>
  23. </Window>_categoryList = value;            }        }        private Category _selectedCategory;        public Category SelectedCategory        {            get            {<Window x:
  24.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  25.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  26.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  27.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  28.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  29.         mc:Ignorable="d"
  30.         Title="ShellView" Height="450" Width="800">
  31.     <Grid>
  32.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  33.     </Grid>
  34. </Window>return _selectedCategory;            }            set            {<Window x:
  35.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  36.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  37.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  38.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  39.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  40.         mc:Ignorable="d"
  41.         Title="ShellView" Height="450" Width="800">
  42.     <Grid>
  43.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  44.     </Grid>
  45. </Window>_selectedCategory = value;<Window x:
  46.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  47.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  48.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  49.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  50.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  51.         mc:Ignorable="d"
  52.         Title="ShellView" Height="450" Width="800">
  53.     <Grid>
  54.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  55.     </Grid>
  56. </Window>NotifyOfPropertyChange(nameof(SelectedCategory));<Window x:
  57.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  58.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  59.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  60.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  61.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  62.         mc:Ignorable="d"
  63.         Title="ShellView" Height="450" Width="800">
  64.     <Grid>
  65.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  66.     </Grid>
  67. </Window>NotifyOfPropertyChange(() => CanEdit);<Window x:
  68.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  69.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  70.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  71.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  72.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  73.         mc:Ignorable="d"
  74.         Title="ShellView" Height="450" Width="800">
  75.     <Grid>
  76.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  77.     </Grid>
  78. </Window>NotifyOfPropertyChange(() => CanDelete);            }        }        private string _categoryName;        public string CategoryName        {            get => _categoryName; set            {<Window x:
  79.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  80.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  81.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  82.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  83.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  84.         mc:Ignorable="d"
  85.         Title="ShellView" Height="450" Width="800">
  86.     <Grid>
  87.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  88.     </Grid>
  89. </Window>_categoryName = value;<Window x:
  90.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  91.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  92.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  93.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  94.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  95.         mc:Ignorable="d"
  96.         Title="ShellView" Height="450" Width="800">
  97.     <Grid>
  98.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  99.     </Grid>
  100. </Window>NotifyOfPropertyChange(nameof(CategoryName));            }        }<Window x:
  101.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  102.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  103.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  104.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  105.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  106.         mc:Ignorable="d"
  107.         Title="ShellView" Height="450" Width="800">
  108.     <Grid>
  109.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  110.     </Grid>
  111. </Window>private string _categoryDescription;        public string CategoryDescription        {            get => _categoryDescription; set            {<Window x:
  112.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  113.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  114.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  115.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  116.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  117.         mc:Ignorable="d"
  118.         Title="ShellView" Height="450" Width="800">
  119.     <Grid>
  120.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  121.     </Grid>
  122. </Window>_categoryDescription = value;<Window x:
  123.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  124.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  125.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  126.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  127.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  128.         mc:Ignorable="d"
  129.         Title="ShellView" Height="450" Width="800">
  130.     <Grid>
  131.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  132.     </Grid>
  133. </Window>NotifyOfPropertyChange(nameof(CategoryDescription));            }        }        protected override void OnViewLoaded(object view)        {            base.OnViewLoaded(view);            CategoryList.Add(new Category { Id=1, Name = "Meals", Description = "Lunched and diners" });            CategoryList.Add(new Category { Id=2, Name = "Representation", Description = "Gifts for our customers" });        }        public bool CanEdit        {            get            {<Window x:
  134.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  135.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  136.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  137.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  138.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  139.         mc:Ignorable="d"
  140.         Title="ShellView" Height="450" Width="800">
  141.     <Grid>
  142.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  143.     </Grid>
  144. </Window>return SelectedCategory != null;            }        }        public void Edit()        {            CategoryName = SelectedCategory.Name;            CategoryDescription = SelectedCategory.Description;        }        public bool CanDelete        {            get            {<Window x:
  145.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  146.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  147.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  148.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  149.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  150.         mc:Ignorable="d"
  151.         Title="ShellView" Height="450" Width="800">
  152.     <Grid>
  153.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  154.     </Grid>
  155. </Window>return SelectedCategory != null;            }        }        public void Delete()        {            CategoryList.Remove(SelectedCategory);            Clear();        }        public void Save()        {            Category newCategory = new Category();            newCategory.Name = CategoryName;            newCategory.Description = CategoryDescription;            if (SelectedCategory != null)            {<Window x:
  156.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  157.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  158.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  159.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  160.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  161.         mc:Ignorable="d"
  162.         Title="ShellView" Height="450" Width="800">
  163.     <Grid>
  164.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  165.     </Grid>
  166. </Window>CategoryList.Remove(SelectedCategory);            }            CategoryList.Add(newCategory);            Clear();        }        public void Clear()        {            CategoryName = string.Empty;            CategoryDescription = string.Empty;            SelectedCategory = null;        }    }}
复制代码
在ShellViewModel中挂载CategoryViewModel,起首在创建一个方法,此方法主要用于从Ioc容器中获取CategoryViewModel的实例,并调用ActivateItemAsync激活此实例。
  1. public Task EditCategories()
  2. {
  3.     var viewmodel = IoC.Get<CategoryViewModel>();
  4.     return ActivateItemAsync(viewmodel, new CancellationToken());
  5. }
复制代码
重载ShellViewModel的OnViewLoaded方法,并在此方法中调用EditCategories方法。 
  1. protected async override void OnViewLoaded(object view)
  2. {
  3.     base.OnViewLoaded(view);
  4.     await EditCategories();
  5. }
复制代码
创建视图CategoryView.xaml,并保存在Views目录下,在此视图中DataGrid主要用到两个属性ItemsSource和SelectedItem。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application>        
复制代码
文本框TextBox的绑定采用定名约定,将文本的名称x:Name和CategoryViewModel中的属性保持一致,就可自动绑定。
  1.     Edit Category            Category Name<Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application>Category Description<Application x:
  10.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  11.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  12.              xmlns:local="clr-namespace:DemoCaliburn">
  13.     <Application.Resources>
  14.         <ResourceDictionary>
  15.         </ResourceDictionary>
  16.     </Application.Resources>
  17. </Application>Save        Clear   
复制代码
Button按钮,也可以不写OnClick变乱,通过定名约定,将CategoryViewModel中的方法和Button自动绑定。 
  1. <WrapPanel>
  2.         <Button x:Name="Edit" Width="80" Margin="5">Edit</Button>
  3.         <Button x:Name="Delete" Width="80" Margin="5">Delete</Button>
  4. </WrapPanel>
复制代码
条件实行,如果属性的名称以Can开头,后跟方法名称,如方法Edit对应的属性CanEdit,遵循此定名约定,则可以根据属性的返回值控制按钮是否答应实行。如:当列表没有选中项时,Edit按钮不可用 
  1. public bool CanEdit
  2. {
  3.         get
  4.         {
  5.                 return SelectedCategory != null;
  6.         }
  7. }
  8. public void Edit()
  9. {
  10.         CategoryName = SelectedCategory.Name;
  11.         CategoryDescription = SelectedCategory.Description;
  12. }
复制代码

菜单,前面报告了MVVM的基础功能,接下来继承解说菜单,主要是在ShellView页面添加菜单。
  1. <Menu>
  2.         <MenuItem x:Name="FileMenu" Header="File" IsEnabled="{Binding CanFileMenu}"/>
  3.         <MenuItem Header="Edit"/>
  4.         <MenuItem Header="Settings">
  5.                 <MenuItem x:Name="EditCategories" Header="Edit Categories"/>
  6.         </MenuItem>
  7.         <MenuItem Header="Help">
  8.                 <MenuItem Header="Manual"/>
  9.                 <MenuItem x:Name="About" Header="About"/>
  10.         </MenuItem>
  11. </Menu>
复制代码
MenuItems看起来好像不支持直接定名约定,为了启用或者禁用一个MenuItem,需要增加依赖属性绑定。如:在ViewModel中,增加一个CanFileMenu属性,来控制FileMenu的使用。当然需要在其他属性变化时,通过PropertyChanged变瞎搅关照它的变化来实现动态控制。 
  1. public bool CanFileMenu
  2. {
  3.         get
  4.         {
  5.                 return false;
  6.         }
  7. }
复制代码

弹出窗口,起首创建AboutView.xaml,并保存在Views文件夹下,用于弹出关于窗口页面。
  1. <Application x:
  2.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.              xmlns:local="clr-namespace:DemoCaliburn">
  5.     <Application.Resources>
  6.         <ResourceDictionary>
  7.         </ResourceDictionary>
  8.     </Application.Resources>
  9. </Application><Application x:
  10.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  11.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  12.              xmlns:local="clr-namespace:DemoCaliburn">
  13.     <Application.Resources>
  14.         <ResourceDictionary>
  15.         </ResourceDictionary>
  16.     </Application.Resources>
  17. </Application><Application x:
  18.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  19.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  20.              xmlns:local="clr-namespace:DemoCaliburn">
  21.     <Application.Resources>
  22.         <ResourceDictionary>
  23.         </ResourceDictionary>
  24.     </Application.Resources>
  25. </Application><Application x:
  26.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  27.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  28.              xmlns:local="clr-namespace:DemoCaliburn">
  29.     <Application.Resources>
  30.         <ResourceDictionary>
  31.         </ResourceDictionary>
  32.     </Application.Resources>
  33. </Application><Application x:
  34.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  35.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  36.              xmlns:local="clr-namespace:DemoCaliburn">
  37.     <Application.Resources>
  38.         <ResourceDictionary>
  39.         </ResourceDictionary>
  40.     </Application.Resources>
  41. </Application><Application x:
  42.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  43.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  44.              xmlns:local="clr-namespace:DemoCaliburn">
  45.     <Application.Resources>
  46.         <ResourceDictionary>
  47.         </ResourceDictionary>
  48.     </Application.Resources>
  49. </Application><Application x:
  50.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  51.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  52.              xmlns:local="clr-namespace:DemoCaliburn">
  53.     <Application.Resources>
  54.         <ResourceDictionary>
  55.         </ResourceDictionary>
  56.     </Application.Resources>
  57. </Application><Application x:
  58.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  59.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  60.              xmlns:local="clr-namespace:DemoCaliburn">
  61.     <Application.Resources>
  62.         <ResourceDictionary>
  63.         </ResourceDictionary>
  64.     </Application.Resources>
  65. </Application>        Program name:<Application x:
  66.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  67.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  68.              xmlns:local="clr-namespace:DemoCaliburn">
  69.     <Application.Resources>
  70.         <ResourceDictionary>
  71.         </ResourceDictionary>
  72.     </Application.Resources>
  73. </Application>Program version:<Application x:
  74.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  75.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  76.              xmlns:local="clr-namespace:DemoCaliburn">
  77.     <Application.Resources>
  78.         <ResourceDictionary>
  79.         </ResourceDictionary>
  80.     </Application.Resources>
  81. </Application>Author:<Application x:
  82.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  83.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  84.              xmlns:local="clr-namespace:DemoCaliburn">
  85.     <Application.Resources>
  86.         <ResourceDictionary>
  87.         </ResourceDictionary>
  88.     </Application.Resources>
  89. </Application>More information:<Application x:
  90.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  91.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  92.              xmlns:local="clr-namespace:DemoCaliburn">
  93.     <Application.Resources>
  94.         <ResourceDictionary>
  95.         </ResourceDictionary>
  96.     </Application.Resources>
  97. </Application><Application x:
  98.              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  99.              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  100.              xmlns:local="clr-namespace:DemoCaliburn">
  101.     <Application.Resources>
  102.         <ResourceDictionary>
  103.         </ResourceDictionary>
  104.     </Application.Resources>
  105. </Application><Window x:
  106.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  107.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  108.         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  109.         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  110.         xmlns:local="clr-namespace:DemoCaliburn.Views"
  111.         mc:Ignorable="d"
  112.         Title="ShellView" Height="450" Width="800">
  113.     <Grid>
  114.         <ContentControl x:Name="ActiveItem" Margin="20"/>
  115.     </Grid>
  116. </Window>Close   
复制代码
此中点击超链接变乱在后台隐藏代码中。 
  1. public partial class AboutView : Window
  2. {
  3.         public AboutView()
  4.         {
  5.                 InitializeComponent();
  6.         }
  7.         private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
  8.         {
  9.                 var psi = new ProcessStartInfo
  10.                 {
  11.                         FileName = e.Uri.AbsoluteUri,
  12.                         UseShellExecute = true
  13.                 };
  14.                 Process.Start(psi);
  15.         }
  16. }
复制代码
AboutView视图对应的模型为About。创建模型,并保存在Models目录。
  1. public class About
  2. {
  3.         public string Title { get; set; } = "Caliburn.Micro 示例";
  4.         public string Version { get; set; } = "1.0";
  5.         public string Author { get; set; } = "老码识途";
  6.         public string Url { get; set; } = "老码识途";
  7. }
复制代码
创建AboutViewModel并保存在ViewModels目录下,此中属性AboutData主要用于绑定页面属性。
  1. public class AboutViewModel : Screen
  2. {
  3.         public AboutViewModel()
  4.         {
  5.         }
  6.         private About _aboutData = new About();
  7.         public About AboutData
  8.         {
  9.                 get { return _aboutData; }
  10.         }
  11.         public Task CloseForm()
  12.         {
  13.                 //TryClose(true); // for OK
  14.                 //TryClose(false); // for Cancel
  15.                 return TryCloseAsync();
  16.         }
  17. }
复制代码
ViewModel中属性和View页面采用定名约定,x:Name=”属性名”,主要属性类型为自界说的类,则子属性名与视图绑定也遵循定名约定,两个属性名用下划线毗连,如x:Name=”属性名_子属性名” 
弹出窗口需要用到IWindowManager接口,在ViewModel的构造函数进行注入。
  1. private readonly IWindowManager _windowManager;
  2. public ShellViewModel(IWindowManager windowManager)
  3. {
  4.         _windowManager = windowManager;
  5. }
复制代码
创建菜单About定名约定的函数About方法。在方法中通过windowManager的ShowDialogAsync方法弹出窗口。且ShowDialogAsync方法返回一个bool?类型的值,表示是否ok. 
  1. public Task About()
  2. {
  3.     return _windowManager.ShowDialogAsync(IoC.Get<AboutViewModel>());
  4. }
复制代码
除了弹出模态窗口,还可以弹出窗口的其他变体,如:非模态窗口,鼠标位置弹出Popup窗口等。 在弹出窗口时,还可以设置窗口的一些参数,此参数为IDictionary类型的字典。 
  1. public Task About()
  2. {
  3.         //dynamic settings = new ExpandoObject();
  4.         //settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
  5.         //settings.ResizeMode = ResizeMode.NoResize;
  6.         //settings.MinWidth = 450;
  7.         //settings.Title = "My New Window";
  8.         //settings.Icon = new BitmapImage(new Uri("pack://application:,,,/MyApplication;component/Assets/myicon.ico"));
  9.         //IWindowManager manager = new WindowManager();
  10.         //manager.ShowDialog(myViewModel, null, settings);
  11.         //_windowManager.ShowPopupAsync(IoC.Get<AboutViewModel>()); //当前鼠标位置显示一个弹出表单
  12.         //_windowManager.ShowWindowAsync(IoC.Get<AboutViewModel>());//普通窗口
  13.         return _windowManager.ShowDialogAsync(IoC.Get<AboutViewModel>());//模态窗口
  14. }
复制代码
 
源码下载

Calibun.Micro是一款开源框架,在Github上可以进行下:
Github网址:https://github.com/Caliburn-Micro/Caliburn.Micro 

 
以上就是《WPF开发框架Caliburn.Micro详解》的全部内容,旨在抛砖引玉,一起学习,共同进步!!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4