WPF入門教程系列二十七 ——DataGrid使用示例MVVM模式(4)

WPF入門教程系列五——Window 介紹

 
 

    計算機界的頂極大牛們,站在金字塔尖的專家們,發明了模式,並大力推廣模式,其目的就是想要達到高內聚低耦合。在WPF開發中,經典的編程模式是MVVM,是爲WPF量身定做的模式,該模式充分利用了WPF的數據綁定機制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI顯示和邏輯代碼的耦合度,如需要更換界面時,邏輯代碼修改很少,甚至不用修改。與WinForm開發相比,我們一般在後臺代碼中會使用控件的名字來操作控件的各種屬性,進行UI更新,而在WPF中通常是通過數據綁定來更新UI;在響應用戶操作上,WinForm是通過控件的事件來處理,而WPF可以使用命令綁定的方式來處理,耦合度將降低。

     MVVM是Model、View、ViewModel的簡寫,MVVM的根本思想就是界面和業務功能進行分離,View的職責就是負責如何顯示數據及發送命令,ViewModel的功能就是如何提供數據和執行命令。各司其職,互不影響。

       在實際的業務場景中我們經常會遇到客戶對界面提出建議要求修改,使用MVVM模式開發,當設計的界面不滿足客戶時,我們僅僅只需要對View作修改,不會影響到ViewModel中的功能代碼,減少了犯錯的機會。隨着功能地增加,系統會越來越複雜,程序會不停的增加View和ViewModel文件,這樣一來會將複雜的界面分離成局部的View,局部的View對應局部的ViewModel,各個不同的功能點可能散落在不同的ViewModel中,每個ViewModel只專注自己職能之內的事情。

        理想情況下界面和邏輯是完全分離的,單方面更改界面時不需要對邏輯代碼改動,同樣的邏輯代碼更改時也不需要更改界面。同一個ViewModel可以使用完全不用的View進行展示,同一個View也可以使用不同的ViewModel以提供不同的操作。

使用MVVM架構具有以下優勢

1、易維護

2、靈活擴展

3、易測試

4、用戶界面設計師與程序開發者能更好的合作

六、下拉框顯示省份,實現保存功能

本篇文章我們來實現按鈕的Click方法也採用綁定的形式,將業務邏輯代碼寫到業務邏輯類中,而不是寫在View的後臺cs文件中,這就需要使用Command指令。

在WPF中使用Command指令的步驟如下:

1)創建命令

2)綁定命令

3)設置命令源

4)設置命令目標

  WPF中Command指令的核心是繼承System.Windows.Input.ICommand接口,所有Command指令對象都實現了此接口。當創建自己的Command指令時,不能直接實現ICommand接口,而是要使用System.Windows.Input.RouteCommand類,該類已經實現了ICommand接口,所有WPF中的Command指令都是RouteCommand類的實例。在程序中處理的大部分Command指令不是RoutedCommand對象,而是RoutedUICommand類的實例,它繼承自RouteCommand類。

   WPF提供了一個很好的方式來解決事件綁定的問題--ICommand。很多控件都有Command屬性,如果沒有,我們可以將Command指令綁定到觸發器上。接下來我們來先實現一個ICommand接口。ICommand需要用戶定義兩個方法bool CanExecute和void Execute。第一個方法可以讓我們來判斷是否可以執行這個命令,第二個方法就是我們具體的命令。

Command--ClickSaveAction

1. 在Visual Studio 2022的“解決方案資源管理器”中,使用鼠標右鍵單擊“WpfGridDemo.NET7”項目,在彈出菜單中選擇“添加-->新建文件夾”。 並將“新文件夾”改名爲 “Command”。

2. 在Visual Studio 2022的解決方案資源管理器中,使用鼠標右鍵單擊“Command”文件夾,在彈出菜單中選擇“添加--> 類”,在彈出的“添加新項”對話框中,選擇添加 “SaveCommand”類,這是一個我們要實現的保存操作指令,然後選擇“添加”。

3.要實現在按鈕的Command上綁定方法,代替Click事件,就需要SaveCommand實現ICommand接口,需要我們自己創建類型去實現接口的CanExecuteExecuteCanExecuteChanged,下面就是實現接口的代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

 

namespace WpfGridDemo.NET7.Command
{

    public class SaveCommand

    {

        /// <summary>
        /// 命令能否執行
        /// </summary>
        readonly Func<bool> _canExecute;

        /// <summary>
        /// 命令執行的方法
        /// </summary>
        readonly Action _execute;

 
        /// <summary>
        /// 命令的構造函數
        /// </summary>
        /// <param name="action">命令需執行的方法</param>
        /// <param name="canExecute">命令是否可以執行的方法</param>
        public SaveCommand(Action action, Func<bool> canExecute)
        {
            _execute = action;
            _canExecute = canExecute;
        }
 
        /// <summary>
        /// 判斷命令是否可以執行
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(Object parameter)
        {
            if (_canExecute == null)
                return true;
            return _canExecute();
        }


        /// <summary>
        /// 執行命令
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(Object parameter)

        {
            _execute();
        }
 
        /// <summary>
        /// 事件追加、移除
        /// </summary>

        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (_canExecute != null)
                    CommandManager.RequerySuggested += value;
            }

            remove
            {

                if (_canExecute != null)

                    CommandManager.RequerySuggested -= value;
            }
        }
    }
}

 

4.SaveCommand類就是爲了在使用命令的時候, 創建一條命令出來用於綁定,這個類型接收兩個參數,一個是命令執行的方法,另一個是有返回值的方法, 這個返回值bool用來確定,該條命令是否可以執行,如果命令不能被執行,則按鈕的IsEnabled就被會設置成不可點擊。

MainWindowVM中創建一個命令

1. 在Visual Studio 2022的“解決方案資源管理器”中,使用鼠標右鍵單擊“WpfGridDemo.NET7”項目,在彈出菜單中選擇“添加-->新建文件夾”。 並將“新文件夾”改名爲 “ViewModel”。

2. 在Visual Studio 2022的解決方案資源管理器中,使用鼠標右鍵單擊“ViewModel”文件夾,在彈出菜單中選擇“添加--> 類”,在彈出的“添加新項”對話框中,選擇添加 “MainWindowVM”類,這是一個ViewModel,然後選擇“添加”。

3.之前我們已經創建了SaveCommand類,並實現了ICommand接口,下面在MainWindowVM中使用SaveCommand類,創建ClickSaveAction方法。

4.由於此次我們使用的是MVVM模塊,無法直接使用界面中的控件DataGrid的屬性,我們要將界面中所做的修改的數據保存到數據,則要在MainWindowVM添加一個綁定屬性AreaVM,用於接收界面中傳遞過來的數據。具體如下代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using WpfGridDemo.NET7.Entitys;
 

namespace WpfGridDemo.NET7.ViewModel
{

    public class MainWindowVM
    {

        private Area m_Area;

        /// <summary>
        /// 員工數據
        /// </summary>
        public Area AreaVM
        {

            get { return m_Area; }

            set { m_Area = value; }
        }

        /// <summary>
        /// 命令要執行的方法
        /// </summary>
        void SaveExecute()

        {

            try 
           {
                    GridDbContext db = new GridDbContext();
                var list=db.Area.AsTracking().ToList();
                Area modifyArea = list.Where(x=>x.Id==AreaVM.Id).FirstOrDefault();

                if (modifyArea != null)
                {

                    modifyArea.Name = AreaVM.Name;
                    modifyArea.Updated = DateTime.Now;
                    db.SaveChanges();

                }
            }

            catch (Exception ex)
            {
                throw ex;
            }

        }
 
        /// <summary>
        /// 命令是否可以執行
        /// </summary>
        /// <returns></returns>
        bool CanSaveExecute()
        {
            return true;
        }

 

        /// <summary>
        /// 創建新命令
        /// </summary>

        public ICommand ClickSaveAction
        {
            get

            {
                return new Command.SaveCommand(SaveExecute, CanSaveExecute);
            }
        }
 
    }
}

注意,創建這個新的命令的名字需要和我們界面按鈕Command中綁定的名字一致,叫ClickSaveAction

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章