1. 程式人生 > 其它 >WPF優秀元件推薦之Stylet(一)

WPF優秀元件推薦之Stylet(一)

Stylet是基於WPF的一款MVVM元件,雖然WPF本身是自帶MVVM功能的,但實現起來不是很方便 ,通過Stylet,使用者可以用很少的程式碼就能享受MVVM帶來的舒適體驗。

一、簡介

Stylet是基於WPF的一款MVVM元件,雖然WPF本身是自帶MVVM功能的,但實現起來不是很方便,通過Stylet,使用者可以用很少的程式碼就能享受MVVM帶來的舒適體驗。

目前Stylet支援:.Net Framerwork 4.5、.Net Core 3.0、.Net 5以上版本。

二、搭建基本框架

1、新建專案工程後,通過Nuget新增以下幾個元件:

2、新建視窗MainShellView,新建類MainShellViewModel

public class MainShellViewModel : Stylet.Screen
{
}

Stylet對檢視和模型有命名要求,必須為XXXView、XXXViewModel形式成對出現。

3、新建類Bootstrapper

    public class Bootstrapper : Bootstrapper<MainShellViewModel>
    {
        protected override void ConfigureIoC(IStyletIoCBuilder builder)
        {
            // Configure the IoC container in here
        }

        protected override void Configure()
        {
            
// Perform any other configuration before the application starts } }

4、編輯App.xmal,刪除StartupUri="MainWindow.xaml",如下:

<Application x:Class="NiceComponents.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml
" xmlns:local="clr-namespace:NiceComponents" xmlns:s="https://github.com/canton7/Stylet"> <Application.Resources> <s:ApplicationLoader> <s:ApplicationLoader.Bootstrapper> <local:Bootstrapper /> </s:ApplicationLoader.Bootstrapper> </s:ApplicationLoader> </Application.Resources> </Application>
View Code

然後編譯執行即可。

此時專案根目錄的MainWindow.xaml已經沒有用了,可以刪除。

三、基本用法

1、繫結

XMAL:
<ProgressBar Value="{Binding ProgressValue}" Visibility="{Binding ProgressVisibility}" Maximum="100" />
<Slider Value="{Binding ProgressValue}" Maximum="100" />
<CheckBox Content="Show" IsChecked="{Binding IsProgressShow}"/>

CODE:
public class MainShellViewModel : Stylet.Screen
{
    public int ProgressValue { get; set; }
    public bool IsProgressShow { get; set; } = true;
    public Visibility ProgressVisibility => IsProgressShow ? Visibility.Visible : Visibility.Collapsed;
}

以上程式碼實現一個ProgressBar 控制元件和一個Slider 控制元件的聯動,同時通過一個CheckBox控制元件來控制ProgressBar 是否顯示,程式碼非常簡潔,充分體現了MVVM的優雅。

2、命令

XMAL:
  <TextBox Text="{Binding InputString, UpdateSourceTrigger=PropertyChanged}"/>
  <TextBlock  Text="{Binding OutputString}"/>
  <Button Content="Show" Command="{s:Action ShowString}" />

CODE:
public class MainShellViewModel : Stylet.Screen
 { 
        public string InputString { get; set; }
        public string OutputString { get; set; }
        public void ShowString()
        {
            OutputString = $"Your string is : {InputString}";
        }
        public bool CanShowString => !string.IsNullOrEmpty(InputString);
}

通過Command="{s:Action ShowString}"來呼叫後臺的方法。在方法名稱前加一個Can表示防衛屬性,通過CanShowString屬性可以控制該按鈕的IsEnabled狀態。

某些控制元件沒有Command屬性,也是用同樣方法呼叫:

<TextBox TextChanged="{s:Action TextChanged}" IsEnabled={Binding IsTextBoxEnabled} />

public void TextChanged()
{
      Debug.WriteLine("TextChanged");
}

此時,防衛屬性是不能用的,如果需要,可以定義一個普通的bool型別變數Binding到控制元件的IsEnabled屬性即可。

3、繫結列表

XMAL:
  <ListBox ItemsSource="{Binding StringList}" SelectedItem="{Binding SelectedString}" />
  <Button Content="Add String" Command="{s:Action AddString}" />
  <Button Content="Delete String" Command="{s:Action DeleteString}" />
    
CODE:
    public class MainShellViewModel : Stylet.Screen
    {
public List<string> StringList { get; set; } = new List<string>(); public string SelectedString { get; set; } public void AddString() { StringList.Add($"Item{StringList.Count + 1}"); } public void DeleteString() { StringList.Remove(SelectedString); } public bool CanDeleteString => SelectedString != null; }

WPF中有不少控制元件繫結的資料型別是列表,比如:ListBox、ComboBox、DataGrid等。以上程式碼實現一個列表的增加和刪除。

執行以上程式碼,你會發現程式不能正確執行,通過Debug會發現AddString方法已經執行了,StringList列表數量也增加了,但介面上的ListBox沒有變化。對於MVVM框架而言,這是一個非常常見的問題,也是非常容易犯的錯誤。

當我們改變一個物件時,Fody框架會自動呼叫PropertyChanged方法,前臺收到PropertyChanged事件才會更新介面,對於List而言,呼叫其Add方法只是改變了物件的屬性,並沒有改變物件本身,所以沒有產生PropertyChanged事件。

要解決這個問題,可以採用BindingList來取代List,該類在內容發生變化時也會發送PropertyChanged事件,另外,Stylet框架專門提供一個BindableCollection類來裝載需要動態繫結的列表,應優先使用這個類。

以上程式碼下載地址:NiceComponents · Bruce/Learn WPF - 碼雲 - 開源中國 (gitee.com)

下一節,將會介紹一些Stylet框架的更復雜一些應用。


簽名區:
如果您覺得這篇部落格對您有幫助或啟發,請點選右側【推薦】支援,謝謝!