C# WPF - 利用Blend SDK和Prism框架創建簡單的MVVM設計模式的程序


前言

前幾天學習了劉鐵猛老師的《深入淺出WPF》之MVVM入門與提高教程,仿照教程,用VS2019、Blend SDK和Prism框架創建了簡單的MVVM設計模式的程序。

學習/開發環境

  • Microsoft Visual Studio 2019
  • Microsoft Prism
  • Microsoft Blend SDK

必要的知識准備

  • 熟悉Data Binding和Dependency Property
  • 了解WPF中的命令(ICommand接口)
  • 熟悉Lambda表達式

MVVM設計模式詳解

  • MVVM = Model + View + ViewModel
  • 為什么要使用MVVM
    • 團隊層面: 統一思維方式和實現方法
    • 架構層面:穩定、解耦
    • 代碼層面:易讀、易測、易替換
  • 什么是Model
    • 現實世界中對象的抽象結果
  •  什么是View和ViewModel
    • View = UI
    • ViewModel = View For Model
    • ViewModel與View的溝通
      • 傳遞數據 - 數據屬性
      • 傳遞命名 - 命令屬性

創建WPF項目和NuGet方式添加Blend SDK和Prism框架

創建解決方案並添加Wpf應用程序

NuGet添加

  • Expression.Blend.Sdk.WPF
  • Prism.Wpf

主界面xaml代碼

MainWindow.xaml

解決方案文件結構

在Commands文件夾下創建DelegateCommand對象

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

namespace WpfDemo.Commands
{
    class DelegateCommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// 判斷命令是否可以執行
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter)
        {
            if (this.CanExecuteFunc != null)
            {
                this.CanExecuteFunc(parameter);
            }
            else
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 執行相關的命令
        /// </summary>
        /// <param name="parameter">相關命令</param>
        public void Execute(object parameter)
        {
            if (this.ExecuteAction == null)
            {
                return;
            }
            this.ExecuteAction(parameter);
        }

        /// <summary>
        /// 聲明一個委托用來執行命令對應的方法
        /// </summary>
        public Action<object> ExecuteAction { get; set; }

        /// <summary>
        /// 聲明一個方法,用來判斷命令是否可以被執行
        /// </summary>
        public Func<object, bool> CanExecuteFunc { get; set; }
    
    }
}
DelegateCommand.cs

在ViewModels文件夾下分別創建NotificationObject和MainWindowViewModel對象

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfDemo.ViewModels
{
    //繼承負責通知View的接口
    class NotificationObject : INotifyPropertyChanged
    {
        // 接口的實現
        public event PropertyChangedEventHandler PropertyChanged;

        // 封裝一個方法用來通知
        public void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }
}
NotificationObject.cs
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfDemo.Commands;

namespace WpfDemo.ViewModels
{
    class MainWindowViewModel : NotificationObject
    {
        /// <summary>
        /// 數據屬性
        /// 輸入值1
        /// </summary>
        private double input1;

        public double Input1
        {
            get { return input1; }
            set
            {
                input1 = value;
                this.RaisePropertyChanged("Input1");
            }
        }

        /// <summary>
        /// 數據屬性
        /// 輸入值2
        /// </summary>
        private double input2;

        public double Input2
        {
            get { return input2; }
            set
            {
                input2 = value;
                this.RaisePropertyChanged("Input2");
            }
        }

        /// <summary>
        /// 數據屬性
        /// 返回值1
        /// </summary>
        private double result;

        public double Result
        {
            get { return result; }
            set
            {
                result = value;
                this.RaisePropertyChanged("Result");
            }
        }


        public DelegateCommand AddCommand { get; set; }
        public DelegateCommand SaveCommand { get; set; }

        /// <summary>
        /// 加法運算
        /// </summary>
        /// <param name="parameter"></param>
        private void Add(object parameter)
        {
            this.Result = this.Input2 + this.Input1;
        }

        /// <summary>
        /// 打開保存對話框
        /// </summary>
        /// <param name="parameter"></param>
        private void Save(object parameter)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.ShowDialog();
        }

        public MainWindowViewModel()
        {
            // 讓Add和AddCommand關聯起來
            this.AddCommand = new DelegateCommand();
            this.AddCommand.ExecuteAction = new Action<object>(this.Add);

            // 讓Save和SaveCommand關聯起來
            this.SaveCommand = new DelegateCommand();
            this.SaveCommand.ExecuteAction = new Action<object>(this.Save);
        }
    }
}
MainWindowViewModel.cs

輸入框綁定數據屬性、按鈕綁定命令屬性

<TextBox Text="{Binding Input1}" Grid.Row="0" />
<TextBox Text="{Binding Input2}" Grid.Row="1" />
<TextBox Text="{Binding Result}" Grid.Row="2" />
<Button Command="{Binding AddCommand}" Grid.Row="3"  Content="Plus"/>
<Button Command="{Binding SaveCommand}" Grid.Row="3"  Content="Save"/>

注意:綁定內容要與ViewModel中的屬性名一致;

最后,建立DataContext指向MainWindowViewModel,即this.DataContext = new MainWindowViewModel(); 

  作者:Jeremy.Wu
  出處:https://www.cnblogs.com/jeremywucnblog/
  本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM