Stylet是一个适用于WPF的轻量MVVM框架
特性
- VM优先
经典的MVVM架构,View会实例化ViewModel ,ViewModel不知道View的存在
Stylet需要手动实例化VM,自动附加View - Actions
可以绑定Command,也可以绑定Events - Screen和Conductors
Screen类是VM的基类,提供了属性通知,验证,显示,隐藏,关闭的通知 - 事件总线
隔离订阅者和发送者 - WindowManager
可以通过VM显示对话框 - 验证
Stylet可以使用FluentValidation向视图报告结果 - IOC控制反转
内置IOC,也可以换成第三方
简单入门
以.netframework为例 手动搭建
- 新建WPF应用
- 打开NuGet 安装Stylet包(1.3.4)
- 删掉MainWindow
- 创建一个root View 和一个ViewModel(RootView必须是Window ,RootViewModel是普通类,可以继承Screen)
- 创建一个类Bootstrapper 继承自Bootstrapper
public class Bootstrapper : Bootstrapper<RootViewModel>
{
}
- 删掉App.Xaml中的StartUri 添加引用 xmlns:s=“https://github.com/canton7/Stylet”, 在Resources中添加
<s:ApplicationLoader>
<s:ApplicationLoader.Bootstrapper>
<local:Bootstrapper/>
</s:ApplicationLoader.Bootstrapper>
</s:ApplicationLoader>
Bootstrapper
bootstrapper负责引用应用程序,配置IoC容器,实例化root ViewModel并使用WindowManager显示
bootstrapper 有两种形式
- BootstrapperBase 可以配置IoC容器
封装好的第三方容器类,需要手动引入容器包
https://github.com/canton7/Stylet/tree/master/Bootstrappers
把上面的bootstrapper类复制到工程里,创建子类继承它
public class Bootstrapper : AutofacBootstrapper<ShellViewModel>
{
}
- Bootstrapper 使用内置的IoC容器
class Bootstrapper : Bootstrapper<MyRootViewModel>
{
protected override void OnStart()
{
// This is called just after the application is started, but before the IoC container is set up.
// Set up things like logging, etc
}
protected override void ConfigureIoC(IStyletIoCBuilder builder)
{
// Bind your own types. Concrete types are automatically self-bound.
builder.Bind<IMyInterface>().To<MyType>();
}
protected override void Configure()
{
// This is called after Stylet has created the IoC container, so this.Container exists, but before the
// Root ViewModel is launched.
// Configure your services, etc, in here
}
protected override void OnLaunch()
{
// This is called just after the root ViewModel has been launched
// Something like a version check that displays a dialog might be launched from here
}
protected override void OnExit(ExitEventArgs e)
{
// Called on Application.Exit
}
protected override void OnUnhandledException(DispatcherUnhandledExceptionEventArgs e)
{
// Called on Application.DispatcherUnhandledException
}
}
视图模型优先
视图模型优先中的ViewModel依然不知道View,但View不再负责构建ViewModel,而是通过第三方服务给ViewModel定位正确的View(通过命名方式),并设置DataContext。
这样一个ViewModel可以通过其它ViewModel创建
public class ShellViewModel
{
public TopBarViewModel TopBar {
get; private set; }
// Stuff to instantiate and assign TopBarViewModel
}
Actions
通过Command="{s:Action DoSomething}" 绑定到视图中的Command
CommandParameter=“Hello” 用于传参
守卫属性
只读属性"Can"指示Command是否可用
Events
关联的Action有三种形式
public void HasNoArguments() {
}
// This can accept EventArgs, or a subclass of EventArgs
public void HasOneSingleArgument(EventArgs e) {
}
// Again, a subclass of EventArgs is OK