Xamarin 的 MVVM 之 Caliburn.Micro

约定

Caliburn.Micro 以下简称 CM
Xamarin.Form 以下简称 XF

 

摘要
CM 当前已释出 3.0 beta 版
https://github.com/Caliburn-Micro/Caliburn.Micro/tree/3.0.0
对 Xamarin 做了很多支持.


本文主要探索一下, XF 下如何使用 CM, 其它方面不做深入研究.

示例地址:
https://github.com/gruan01/Xamarin-Example/tree/master/CMTest

 

环境
在 Nuget 上, 已经有 CM 对 XF 的支持包:
Caliburn.Micro.Xamarin.Forms 3.0.0-beta1
这个包依赖于:
Caliburn.Micro.Core (= 3.0.0-beta1)
Xamarin.Forms (≥ 1.4.2.6355)

但是如果你只安装了上面这两个依赖, 编译是通不过的. 会提示:
无法加载: Caliburn.Micro.Platform.Core

当前这个 Platform.Core 在 Nuget 上是没有的, 需要自行下载 CM 的 3.0 beta 版, 编译,从而得到这个 dll
这里提供已编译的 DLL:
https://github.com/gruan01/Xamarin-Example/tree/master/CMTest/dll

 

Android 入口, Application

这个很简单, 主要是要在它里面实现一个 IoC 容器 SimpleContainer, 具体参考:
https://github.com/gruan01/Xamarin-Example/blob/master/CMTest/CMTest.Droid/Application.cs

 

WP 入口

这个稍微复杂一点:

1, 新建一个 Bootstrapper , 继承自 PhoneBootStrapperBase
它里面做的事情和 Android 下面的 Applicaton 做的事情基本一致, 也是要声明一个 IoC, 只不过是 SimpleContainer 的子类:
PhoneContainer, 这个类在 Caliburn.Micro.Extensions.dll 里.
除 Configure方法 和 Android 下的 Application 不一样外,其它都一样.
参考:
https://github.com/gruan01/Xamarin-Example/blob/master/CMTest/CMTest.WinPhone/Bootstrapper.cs

 

2, 修改 App.xaml 为以下的样子:

 1 <Application
 2 x:Class="CMTest.WinPhone.App"
 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 5 xmlns:local="clr-namespace:CMTest.WinPhone"
 6 >
 7 
 8 <Application.Resources>
 9 <local:Bootstrapper x:Key="Bootstrapper" />
10 </Application.Resources>
11 </Application>

 

3, 修改 App.xaml.cs 为如下:

1 public partial class App {
2 
3 public App() {
4 this.InitializeComponent();
5 }
6 
7 }

 

 

IOS入口

暂缺

 

XF 项目的 App

https://github.com/gruan01/Xamarin-Example/blob/master/CMTest/CMTest/App.cs

1,需要继承自 FormsApplicaton
2,构造函数中需要加上 SimpleContainer 类型的参数.
3,用 SimpleContainer 注册相关的 ViewModel 为 PerRequest 或 Singleton,
当然也可以不注册, 如果不注册的话, 在使用 INavigationService.For<xxx>.Navigate 的时候,相关 ViewModel 不会被实例, 作者是这样解释
的:
https://github.com/Caliburn-Micro/Caliburn.Micro/issues/182#issuecomment-132356227

The navigation service uses the view model locator to find the appropriate view model, this in turn uses IoC.

If you're not wanting to use dependency injection and all your view models have parameterless constructors then you can pull 
out all of the container code and the framework will just new up the view model.

If you want to use dependency injection then you can choose to use the SimpleContainer that comes with Caliburn or your 
container of choice instead.

The behavior of SimpleContainer is to return null when being asked for a instance it doesn't know about (hence the 
registration). Other containers have different behavior for this, it's up to you which you want to use.

Navigation Service 使用 IoC 中注册的 View Model ,不注册当然是视为你要自己实例化相关 View Model.

其实我提这个问题的目的是想如果加上默认注册 View Model 的功能, 那就在好不过了. 当然了, 我并没有深入了解 CM, 所以只能哈哈了.

 

 

绑定语法

使用过 CM 的, 对它提供的绑定方式一定很赞, 控件的 x:Name 只要和 ViewModel 中的提供的 属性 或 方法名一致, 就可以自动绑定, 如:
...
public string UserName{get;set;}
...
<TextBlock x:Name="UserName" />

会自动绑定 UserName 到 Text 上.

..
public void DoSomthing(){
...
}
...
<Button x:Name="DoSomthing" Content="XXX" />
会自动绑定 button 事件到 DoSomthing 方法上.

 

但是 XF 的对象不能通过 x:Name 获取到, 所以无法使用上面的特性, 要实现绑定, 只能用这下面的方式:
1, 数据绑定 XXX="{Binding xxx}"
2, 事件绑定 cm:Message.Attach="xxx"

http://caliburnmicro.com/announcements/

There is no programmatic access to x:Name in Xamarin.Forms, therefore the feature of name based conventions will not be
available, you will need to use normal {Binding Username} and cm:Message.Attach="SignIn".

这一点, 希望 Xamarin 能在后期的版本中提供支持.

 


子视图

如果你使用过 CM ,那一定对另外一个功能也很赞:
<ContentControl x:Name="SubVM" />
只要 ViewModel 中存在这个 SubVM , 就会把它对应的 View 给展示出来.
在 XF 中, 也支持这个功能, 不过要这样写:

<ContentView cal:View.Model="{Binding VM}" />

具体参见:
https://github.com/gruan01/Xamarin-Example/blob/master/CMTest/CMTest/ViewModels/UserInfoViewModel.cs
看一下动态切换子视图的效果:

Xamarin 的 MVVM 之 Caliburn.Micro_第1张图片

怎么样?是不是想拿它来做个单页应用?

 

你可能感兴趣的:(Xamarin 的 MVVM 之 Caliburn.Micro)