国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

這篇具有很好參考價值的文章主要介紹了循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在前面隨筆《循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(1)》中介紹了Mvvm 的開發(fā),以及一些界面效果,本篇隨筆繼續(xù)深入探討基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā),介紹如何整合SqlSugar框架的基礎(chǔ)接口,通過基類繼承的方式,簡化實際項目的開發(fā)代碼處理。

1、View模塊中的XAML格式說明

在介紹MVVM幾個部分內(nèi)容之前,我們先連接一下View模塊中的Xaml格式的說明,我們知道Xaml也是一個xml的擴展,屬于標(biāo)記語言的一種,編輯器為了更好的驗證格式以及提出上下文的智能提示,必然需要確定對應(yīng)標(biāo)記元素的格式,這個就是通過Xaml的頭部定義確立了,如下所示。

<Page
    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:WHC.SugarProject.WpfUI.Views.Pages"

    x:Class="WHC.SugarProject.WpfUI.Views.Pages.UserListPage"
    d:DataContext="{d:DesignInstance local:UserListPage,
                                     IsDesignTimeCreatable=False}"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">

其中紅色部分基本上是約定需要輸入的定義了,主要是通過xmlns來定義定義XML的校驗格式,類似我們常用的命名空間的引用地址了。

    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?也是定義了本地的XML命名空間。

xmlns:local="clr-namespace:WHC.SugarProject.WpfUI.Views.Pages"

便于在界面元素標(biāo)記中引用對應(yīng)的控件等。而x:Class則是確定XAML的后臺代碼文件的全名稱,使用過早期ASPX的都知道,ASPX文件有一個后臺代碼文件,同理XAML也是類似的概念。

x:Class="WHC.SugarProject.WpfUI.Views.Pages.UserListPage"

而d:開始的那些設(shè)置,是指設(shè)計樣式下的一些屬性定義,如下所示定義設(shè)計窗體的大小,實際運行可能和這個不一樣,因為WPF是屬于矢量的尺寸標(biāo)記的。

    d:DesignHeight="450"
    d:DesignWidth="800"

d:DataContext則是聲明View和模型綁定的一個重要的說明,界面視圖View可以綁定模型的命令Command,也可以綁定對應(yīng)的集合或者屬性等。其中l(wèi)ocal:UserListPage,就是通過簡寫命名控件local和UserListPage類的組合,實現(xiàn)一個全名稱的快速定義。而IsDesignTimeCreatable則是說明設(shè)計狀態(tài)下的數(shù)據(jù)處理方式。

    d:DataContext="{d:DesignInstance local:UserListPage,
                                     IsDesignTimeCreatable=False}"

有時候,我們可能在窗口或者頁面視圖的定義中,還會看到一些其他命名空間的定義或者屬性的定義,如下代碼所示。

<Page
    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:WHC.SugarProject.WpfUI.Views.Pages"

    xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
    xmlns:helpers="clr-namespace:WHC.SugarProject.WpfUI.Helpers"
    xmlns:hc="https://handyorg.github.io/handycontrol"
    xmlns:Controls="clr-namespace:WHC.SugarProject.WpfUI.Controls"

    x:Class="WHC.SugarProject.WpfUI.Views.Pages.UserListPage"
    d:DataContext="{d:DesignInstance local:UserListPage,
                                     IsDesignTimeCreatable=False}"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">

例如上面的紅色部分,就是一般根據(jù)實際情況增加的一些控件的命名空間的定義,便于引用對應(yīng)的界面控件進(jìn)行使用。

<hc:UniformSpacingPanel
    Margin="0,0,0,20"
    HorizontalAlignment="Right"
    Orientation="Horizontal"
    Spacing="10">
    <Button
        Width="60"
        Height="40"
        Command="{Binding SaveCommand}"
        Content="保存"
        Style="{StaticResource ButtonPrimary}" />
    <Button
        Width="60"
        Height="40"
        Command="{Binding ViewModel.BackCommand}"
        CommandParameter="test"
        Content="關(guān)閉" />
</hc:UniformSpacingPanel>

有時候可能還會看到一些屬性設(shè)置,如背景色,以及是否滾動頁面等設(shè)置。

    Background="{DynamicResource RegionBrush}"
    ScrollViewer.CanContentScroll="true"

?

2、MVVM應(yīng)用中包括Model、View、ViewModel三者內(nèi)容中的處理

?前面我們見到,View視圖中綁定ViewModel模型的時候,使用d:DataConext進(jìn)行定義設(shè)置,確定視圖模型的內(nèi)容,我們剛才介紹的定義是如下所示。

    d:DataContext="{d:DesignInstance local:UserListPage,
                                     IsDesignTimeCreatable=False}"

這里你看到的它映射向其本身,而非具體的Viewmodel,這里沒有錯誤,有些MVVM的設(shè)置指向具體的ViewModel定義。

我們來看看這個UserListPage的后端類的定義,如下所示。

首先我們看到一個如下所示。

namespace WHC.SugarProject.WpfUI.Views.Pages;

/// <summary>
/// UserListPage.xaml 交互邏輯
/// </summary>
public partial class UserListPage : INavigableView<UserListViewModel>
{
    /// <summary>
    /// 視圖模型對象
    /// </summary>
    public UserListViewModel ViewModel { get; }

    /// <summary>
    /// 構(gòu)造函數(shù)
    /// </summary>
    /// <param name="viewModel">視圖模型對象</param>
    public UserListPage(UserListViewModel viewModel)
    {
        ViewModel = viewModel;
        DataContext = this;

        InitializeComponent();
    }
}

這里通過泛型接口的方式,定義一個具體類型的視圖模型給視圖View使用。

其中INavigableView接口的定義如下。

public interface INavigableView<out T>
{
    /// <summary>
    /// 視圖的 ViewModel
    /// </summary>
    T ViewModel { get; }
}

這樣我們在Xaml視圖里面,就可以綁定屬性,也可以綁定相應(yīng)的Command命令了,可以是類的,也可以是ViewModel的內(nèi)容。

例如我們在綁定查詢條件處理數(shù)據(jù)查詢的操作的時候,

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?其中界面查詢條件定義了一個文本框名稱的控件,如下所示。

<TextBox
    Margin="5"
    hc:TitleElement.Title="用戶賬號"
    hc:TitleElement.TitlePlacement="Left"
    Style="{StaticResource TextBoxExtend}"
    Text="{Binding ViewModel.PageDto.Name, UpdateSourceTrigger=PropertyChanged}">
    <TextBox.InputBindings>
        <KeyBinding Key="Enter" Command="{Binding ViewModel.SearchCommand}" />
    </TextBox.InputBindings>
</TextBox>

我們通過?{Binding ViewModel.PageDto.Name, UpdateSourceTrigger=PropertyChanged} 的方式綁定文本的界面顯示內(nèi)容和后端模型屬性的,并且在綁定的控件屬性變化的時候觸發(fā)更新。這樣只要界面上輸入的內(nèi)部發(fā)生變化,后端綁定的查詢屬性馬上得到更新,我們就可以即時的通過查詢觸發(fā)獲得相應(yīng)條件的記錄了。

另外通過?InputBindings 的方式,接收Enter內(nèi)容后馬上觸發(fā)查詢處理的命令。

查詢的時候,我們在視圖模型上定義一個RelayCommand的特性標(biāo)注,聲明這個生成的Command為視圖提供處理命令的。

    /// <summary>
    /// 觸發(fā)查詢處理命令
    /// </summary>
    /// <returns></returns>
    [RelayCommand]
    private async Task Search()
    {
        //切換第一頁
        this.PagerInfo.CurrentPageIndex = 1;

        //轉(zhuǎn)換下分頁信息
        ConvertPagingInfo();
        //查詢更新
        await GetData();
    }

然后我們通過轉(zhuǎn)換分頁條件的信息,獲得查詢條件后進(jìn)行服務(wù)接口的調(diào)用,獲取相應(yīng)條件的數(shù)據(jù)即可。

這個接口的后端就是SqlSugar框架的標(biāo)準(zhǔn)請求接口了。

    /// <summary>
    /// 根據(jù)分頁和查詢條件查詢,請求數(shù)據(jù)
    /// </summary>
    /// <returns></returns>
    public virtual async Task GetData()
    {
        var result = await service.GetListAsync(this.PageDto);
        if (result != null)
        {
            this.Items = result.Items?.ToList();
            this.PagerInfo.RecordCount = result.TotalCount;
        }
    }

我們看到,由于框架的通用性抽象處理,因此上面的接口應(yīng)該是可以實現(xiàn)更高層次的抽象處理的,因此我們設(shè)計了幾個視圖基類,用于減少代碼的處理。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?其中 ObservableObject 基類是CommunityToolkit.Mvvm模塊里面定義的視圖模型基類,我們定義的通用基類也是基于它繼承過來即可。

其中BaseViewModel用來處理一些通用的視圖模型操作方式,如跳轉(zhuǎn)或者返回等。

而BaseListViewModel則是根據(jù)查詢列表處理的操作界面所需要的視圖模型處理封裝。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

我們看到類定義和我們SqlSugar很多基類定義類似,都是需要通過泛型傳入一些相關(guān)的參數(shù),實現(xiàn)更加通用的控制的。

public abstract partial class BaseListViewModel<TEntity, TKey, TGetListInput> : BaseViewModel, INavigationAware
        where TEntity : class, IEntity<TKey>, new()
        where TGetListInput : IPagedAndSortedResultRequest, new()

由于.net的開發(fā)方式,現(xiàn)在基本上都是以接口注入方式來處理,這個也是一樣,我們通過注入一個常規(guī)服務(wù)接口的類,來實現(xiàn)一些常規(guī)的請求處理。視圖模型類的接口注入如下所示。

    /// <summary>
    /// 通用基礎(chǔ)操作接口
    /// </summary>
    protected IMyCrudService<TEntity, TKey, TGetListInput> service { get; set; }

    /// <summary>
    /// 構(gòu)造函數(shù)
    /// </summary>
    /// <param name="service">操作接口</param>
    /// <param name="navigationService">視圖導(dǎo)航服務(wù)接口</param>
    public BaseListViewModel(IMyCrudService<TEntity, TKey, TGetListInput> service)
    {
        this.service = service;
    }

這樣我們在分頁控件的頁碼變化的時候,就可以觸發(fā)這個基類的命令處理了。

    /// <summary>
    /// 觸發(fā)的分頁處理命令
    /// </summary>
    /// <param name="info"></param>
    /// <returns></returns>
    [RelayCommand]
    private async Task PageUpdated(FunctionEventArgs<int> info)
    {
        //根據(jù)分頁頁碼展示
        this.PagerInfo.CurrentPageIndex = info.Info;

        //轉(zhuǎn)換下分頁信息
        ConvertPagingInfo();
        //查詢更新
        await GetData();
    }

它的分頁控件部分的視圖界面的代碼如下所示。

<hc:Pagination
    Margin="0,10,0,10"
    DataCountPerPage="{Binding ViewModel.PagerInfo.PageSize}"
    IsJumpEnabled="True"
    MaxPageCount="{Binding ViewModel.PagerInfo.MaxPageCount}"
    MaxPageInterval="5"
    PageIndex="{Binding ViewModel.PagerInfo.CurrentPageIndex}">
    <hc:Interaction.Triggers>
        <hc:EventTrigger EventName="PageUpdated">
            <hc:EventToCommand Command="{Binding ViewModel.PageUpdatedCommand}" PassEventArgsToCommand="True" />
        </hc:EventTrigger>
    </hc:Interaction.Triggers>
</hc:Pagination>

而我們查詢命令,也可以通過下面的基類函數(shù)來處理了。

    /// <summary>
    /// 觸發(fā)查詢處理命令
    /// </summary>
    /// <returns></returns>
    [RelayCommand]
    private async Task Search()
    {
        //切換第一頁
        this.PagerInfo.CurrentPageIndex = 1;

        //轉(zhuǎn)換下分頁信息
        ConvertPagingInfo();
        //查詢更新
        await GetData();
    }

這樣我們在前面介紹的文本框的TextBox的InputBindings處理就可以直接使用這個RelayCommand聲明的命令函數(shù)了。

    <TextBox.InputBindings>
        <KeyBinding Key="Enter" Command="{Binding ViewModel.SearchCommand}" />
    </TextBox.InputBindings>

當(dāng)然,這個基類里面還可以定義其他通用用到的一些常規(guī)處理,如導(dǎo)入導(dǎo)出、刪除和批量刪除等常規(guī)的接口。

而我們在這個用戶業(yè)務(wù)模型里面所需要做的就是做一下繼承關(guān)系的處理即可,如下代碼所示。

namespace WHC.SugarProject.WpfUI.ViewModels;

/// <summary>
/// 用戶列表-視圖模型對象
/// </summary>
public partial class UserListViewModel : BaseListViewModel<UserInfo, int, UserPagedDto>
{
    /// <summary>
    /// 構(gòu)造函數(shù)
    /// </summary>
    /// <param name="service">業(yè)務(wù)服務(wù)接口</param>
    public UserListViewModel(IUserService service) : base(service)
    {
    }
}

這樣?UserListViewModel 就具有了一些通用的業(yè)務(wù)處理對象和命令了,包括常規(guī)的查詢、刪除、批量刪除、導(dǎo)入、導(dǎo)出的處理,都可以了。

同理,對于編輯具體單個記錄的處理,我們也可以使用通用的抽象業(yè)務(wù)類封裝來實現(xiàn),如下代碼所示。

/// <summary>
/// 用戶新增、編輯-視圖模型
/// </summary>
public partial class UserEditViewModel : BaseEditViewModel<UserInfo, int, UserPagedDto>
{
    /// <summary>
    /// 構(gòu)造函數(shù)
    /// </summary>
    /// <param name="service"></param>
    public UserEditViewModel(IUserService service) : base(service)
    {
        this.Title = "用戶信息";
    }
}

至此,整個視圖模型ViewModel的繼承關(guān)系如下所示。對于不同的業(yè)務(wù)類,我們也只需要根據(jù)實際情況,生成對應(yīng)的業(yè)務(wù)視圖模型類即可。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

DataGrid列表展示的處理代碼,主要就是基類觸發(fā)查詢更新后,屬性ViewModel.Items 的記錄獲得更新,這樣DataGrid就可以順利的顯示對應(yīng)的數(shù)據(jù)了,如下界面所示。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?

3、界面的統(tǒng)一處理和代碼生成處理

對于界面上的處理,我們常規(guī)的列表和編輯/新增界面,基本上可以滿足大多數(shù)的要求,如下是列表界面的效果,包括查詢條件、常規(guī)處理按鈕、列表展示、分頁信息展示等幾個部分,如下所示。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?對于一些編輯界面,也是類似下面的布局即可。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?當(dāng)然可以根據(jù)數(shù)據(jù)庫字段進(jìn)行設(shè)置展示那些輸入信息最好了。如對于系統(tǒng)參數(shù)設(shè)置模塊的信息,我們界面如下所示。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?這些內(nèi)容相對比較標(biāo)準(zhǔn)和統(tǒng)一,可以結(jié)合數(shù)據(jù)庫表信息使用統(tǒng)一的方式快速生成即可,因此我把它的生成規(guī)則結(jié)合到我們的代碼生成工具(Database2Sharp)中進(jìn)行生成處理,通過選擇那些字段來實現(xiàn)更加精確的界面處理。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?視圖界面代碼如下所示,包括Xaml和后端類的代碼。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?對應(yīng)有兩個視圖模型ViewModel的繼承類。

循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)

?這樣實現(xiàn),可以極大程度的減少子類的代碼,以及通過代碼生成工具快速定義生成的方式,又可以極大的提高開發(fā)效率,雙管齊下,可以提高整個項目的開發(fā)效率。文章來源地址http://www.zghlxwxcb.cn/news/detail-705974.html

到了這里,關(guān)于循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(2)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包