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/
  本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

posted @ 2020-04-15 14:13  Jeremy.Wu  阅读(1823)  评论(0编辑  收藏  举报