• ViewModel从未如此清爽


    Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家.

    Stylet是受Caliburn Micro项目的启发, 所以借鉴了其中的很多概念, 同时精简了一些部分, 如只支持MVVM, WPF和.NET 4.5(Silverlight和Xamarin不受支持), 所以Style本身很小巧, DLL才140KB左右.

    虽然身材小,但相比知名的MVVM框架, 如MVVM Light等功能却一点都不差,加上很完善的文档,高覆盖率的单元测试,我认为它是一个很有潜力的MVVM框架.

    下面就通过一个类似Hello World的小例子, 给大家演示一下Stylet既简洁又强大的功能.

    创建工程

    创建一个标准的WPF工程, 命名为StyletStudy

    安装Style.Start包

    打开包管理器命令行, 执行以下命令:

    Install-Package Stylet.Start.

    Stylet.Start会自动添加Stylet的引用, 并生成Stylet项目基本的文件, 安装成功后, 项目结构如下所示:

    此时,你就可以按F5启动项目, 看看你的第一个Stylet项目的样子吧.

    绑定属性

    当然,如果只是这样,那么根本没有展现Stylet的魅力, 下面我们加入一些小改动, 用来揭开Stylet美丽的面纱.

    1. ShellViewModel.cs中增加一个Name属性
    2. ShellView.xaml中增加一个TextBox, 绑定Name

    Name属性:

    using Stylet;
    
    namespace StyletStudy.Pages
    {
        public class ShellViewModel : Screen
        {
            public string Name { get; set; } = "waku";  // C#6的语法, 声明自动属性并赋值
        }
    }
    
    

    TextBox:

    <Window x:Class="StyletStudy.Pages.ShellView"
            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:local="clr-namespace:StyletStudy.Pages"
            mc:Ignorable="d"
            Title="Stylet Start Project" Height="350" Width="525"
            xmlns:s="https://github.com/canton7/Stylet"
            d:DataContext="{d:DesignInstance local:ShellViewModel}">
        <StackPanel>
            <TextBox Text="{Binding Name}"></TextBox>
        </StackPanel>
    </Window>
    

    也许你会注意到, 为TextBox设置绑定时, Visual Studio是有智能提示的:

    这是因为贴心的Stylet已经为你将设计时的DataContext设置为ShellViewModel, 注意XAML的第10行:

    d:DataContext="{d:DesignInstance local:ShellViewModel}">
    

    再次启动, 可以看到属性的绑定已经成功了:

    绑定命令

    Stylet中对Command的实现方式深受Caliburn.Micro的影响,这也是Caliburn.Micro一大亮点,即通过命名约定实现Command的绑定.

    1. ShellViewModel.cs中增加一个SayHello方法
    2. ShellView.xaml中增加一个Button, 绑定SayHello

    SayHello方法:

            public string Name { get; set; } = "waku";
    
            public void SayHello() => Name = "Hello " + Name;    // C#6的语法, 表达式方法
    }
    

    SayHello只是简单的在Name前加上"Hello ".

    Button:

        <StackPanel>
            <TextBox Text="{Binding Name}"></TextBox>
            <Button Content="Say Hello" Command="{s:Action SayHello}"></Button>
        </StackPanel>
    

    注意Command="{s:Action SayHello}的语法,s:Action就是Stylet的魔法之一, 如此绑定后, 当点击SayHello按钮后,会自动调用ViewModel中的SayHello方法, 是不是很神奇?

    启动程序,如果你在SayHello中加入一个断点,当点击SayHello按钮后,断点应该就被触发了:

    但是,你会发现文本框中的内容并没有被加上"Hello ",为什么呢?
    如果你是一个合格的WPF程序员,你应该发现了其中的问题: Name属性没有引发PropertyChanged通知

    实现PropertyChanged通知

    MVVM框架一般通过继承一个实现了INotifyPropertyChanged的基类, 然后在属性的set方法中, 引发PropertyChanged通知.
    不同的MVVM框架,可能用一些辅助方法来简化这一过程, 如下面是MVVM Light实现Name属性的方法:

            private string _name;
    
            public string Name
            {
                get { return _name; }
    
                set
                {
                    if (Set(ref _name, value))
                    {
                    }
                }
            }
    

    Stylet也可以用类似的方法来引发PropertyChanged, 但是如果只是那样我文章的标题就需要改名了:)
    为了清爽的ViewModel, Stylet内置了对PropertyChanged.Fody的支持.
    PropertyChanged.Fody是一个非常神奇的包, 它会在编译时为你的属性注入IL代码, 来引发PropertyChanged通知,是不是听上去就非常牛X?

    当然PropertyChanged.Fody不是Stylet专用的,你也可以在你自己的WPF项目中使用该包.
    为Stylet启用PropertyChanged.Fody只需要一条命令安装即可:

    Install-Package PropertyChanged.Fody

    安装后,代码无需任何修改,直接按F5运行.
    再点击SayHello按钮,看看是不是Hello了?

    防护属性(Guard Properties)

    我想当TextBox为空时, 自动禁用SayHello按钮, 这样的需求在开发中很常见.
    Stylet为你考虑到了这一点,你只需要实现一个防护属性即可.
    对于SayHello方法, 实现一个CanSayHello属性, 返回一个bool型结果,标识SayHello是否可被执行.代码如下:

            public void SayHello() => Name = "Hello " + Name;    // C#6的语法, 表达式方法
    
            public bool CanSayHello => !string.IsNullOrEmpty(Name);  // 同上
    

    xaml中也需要为TextBox的绑定做一些修改:

            <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
            <Button Content="Say Hello" Command="{s:Action SayHello}"></Button>
    

    为绑定加上UpdateSourceTrigger=PropertyChanged, 这样只要Name有任何修改,会立即评估CanSayHello属性.

    再次启动项目,看看效果:

    结语

    至此,我们Stylet的入门演示项目就开发完了,
    可以看到ViewModel中我们自己写的代码只有3行,就完成了属性绑定,命令绑定,防护属性功能. 是不是够清爽?

    当然,Stylet还有很多令人激动的特性,解决了长久以来WPF开发中的痛点,如弹出窗体消息框(通过WindowManager), 表单验证(通过ValidatingModelBase),甚至Stylet中还内置了一个性能非常棒的IoC容器.
    强烈建议感兴趣的朋友看看Stylet的WIKI,里面有很多值得学习和参考的东西.

    最后,祝大家工作生活愉快!

  • 相关阅读:
    codeblocks 更换颜色主题
    python3 回顾笔记1
    linux查找目录下的所有文件中是否含有某个字符串
    jupyter notebook 远程访问
    ubuntu ufw防火墙
    加载大量的xml数据 使用压缩方法解决(当然较小时也可以压缩)
    lua string介绍
    Lua和C++交互详细总结
    编写高性能的 Lua 代码
    lua中遍历table的几种方式比较
  • 原文地址:https://www.cnblogs.com/waku/p/6879809.html
Copyright © 2020-2023  润新知