ViewModel從未如此清爽 - 輕量級WPF MVVM框架Stylet

来源:http://www.cnblogs.com/waku/archive/2017/05/19/6879809.html
-Advertisement-
Play Games

"Stylet" 是我最近發現的一個WPF MVVM框架, 在博客園上搜了一下, 相關的文章基本沒有, 所以寫了這個入門的文章推薦給大家. Stylet是受 "Caliburn Micro" 項目的啟發, 所以借鑒了其中的很多概念, 同時精簡了一些部分, 如只支持MVVM, WPF和.NET 4.5 ...


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,裡面有很多值得學習和參考的東西.

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天是個好日子,伴著早上八點的朝陽,我背上書包,提上電腦,帶上一根網線,風風火火的沖向教室,因為,我終於想好博客內容寫啥了——這不是快期末了麽,我就寫複習,雖然有些課程還沒講完,但並不影響我做複習,正好,還能把之前沒學懂的東西揪出來,趁著有網路,有老師,把它們解決掉~ (一)WEB應用基礎 (一)W ...
  • 控制器里的代碼如下: private MySqlDbHelper msh = new MySqlDbHelper(); public ActionResult Index() { string sql = "select * from deviceType"; DataTable dt = msh. ...
  • 作為C 新手中的一員,我剛開始接觸特性時,那真是一臉冏逼啊,怎麼想怎麼查資料都沒弄明白它到底是個什麼東西,有的入門教程甚至都沒講特性和反射這些概念!相信很多人第一次接觸到特性就是關於系列化的知識了。 官方概述: 特性提供功能強大的方法,用以將元數據或聲明信息與代碼(程式集、類型、方法、屬性等)相關聯 ...
  • Newtonsoft.Json.Net20.dll 下載請訪問http://files.cnblogs.com/hualei/Newtonsoft.Json.Net20.rar 在.net 2.0中提取這樣的json {"name":"lily","age":23,"addr":{"city":gu ...
  • 什麼是AOP?引用百度百科:AOP為Aspect Oriented Programming的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。實現AOP主要由兩種方式,一種是編譯時靜態植入,優點是效率高,缺點是缺乏靈活性,.net下postsharp為代表者( ...
  • public class BulletMove : MonoBehaviour { public float Speed = 5f; public Transform Fx; // Use this for initialization void Start () { //5秒後,刪除自己 Dest ...
  • NancyFx框架中使用綁定模型 新建一個空的Web程式 然後安裝Nuget庫裡面的包 Nancy Nancy.Hosting.Aspnet Nancy.ViewEnglines.Spark 併在Web應用程式裡面添加Models,Module,Views三個文件夾 繼續往Models文件夾裡面添加 ...
  • public class PlaneMove : MonoBehaviour { //h:水平方向的控制,v:前後方向的控制 float h,v; //Speed:飛機的飛行速度 public float Speed; // Use this for initialization void Star ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...