第六章:自建MVVM模式的简易项目框架

这篇具有很好参考价值的文章主要介绍了第六章:自建MVVM模式的简易项目框架。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

总目录



前言

前面的几章为我们筑好了MVVM的基础,在这一章中我们将自己搭建一个MVVM模式下的简易项目框架。


一、MVVM是什么?

1.介绍

MVVM是一种模式,主要目的是降低界面和业务逻辑的耦合。
MVVM是Model-View-ViewModel(模型-视图-视图模型)的简写。是WPF开发过程中必不可少的一种开发模式,MVVM基本结构如下图所示:
第六章:自建MVVM模式的简易项目框架

  • View(视图) 就是交互界面,接受用户的输入和展示数据;
  • Model(模型) 是数据模型,项目中的对象,包含属性和行为,项目中的任何事物都可抽象为Model,例如项目中一个用户,我们可以抽象为一个用户的类,可以包含该用户的姓名,出生日期,电话等等信息
  • ViewModel(视图模型)是负责处理业务逻辑的核心。
  • 三者关系:在View和ViewModel中通过数据绑定将界面上元素的依赖属性与实现了INotifyPropertyChanged的ViewModel中的属性进行绑定,实现数据的实时更新机制。在View和ViewModel中通过命令绑定将界面上的操作用Command属性与ViewModel中实现了ICommand的命令进行绑定,实现了用户操作指令的下发。而Model 则是负责给ViewModel提供View所需的对象的数据模型。
  • 通过MVVM这种模式可以最大限度的降低UI界面,数据模型,逻辑业务之间的耦合。让View 将关注点优化呈现效果上,至于数据和操作只需绑定即可;让Model将关注点放在数据模型上,ViewModel将关注点放在处理核心业务逻辑上。

2.优势

  • 低耦合,View可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  • 提高代码重用,可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑;
  • 独立开发,业务开发人员可以专注于业务逻辑和数据的开发,界面开发人员可以专注于页面的开发。

二、搭建MVVM项目框架

现在我们开始着手搭建MVVM项目框架,步骤如下:
(1)首先需要新建一个项目,创建Views,ViewModels,Models 三个文件夹,这样基本结构就搭建好了。

(2)将我们写的xaml页面放在Views目录下,一般就是命名为:xxxView,然后与之对应的视图模型命令为xxxViewModel放在ViewModels目录下,另外将需要的数据模型放置在Models目录下。

(3)再者需要创建一些辅助类的文件目录,一般会创建Resources用于存放一些资源如样式,字体,图片等等,创建一个Helper或者Common的目录,用于存放一些公用的方法类或者帮助类。

具体目录如下图所示:
第六章:自建MVVM模式的简易项目框架
这样一个简易的MVVM项目框架就搭建好了,当然在后面我们会接触到按照MVVM模式已搭建好的比较完善的框架供我们使用。

三、WPF中实现MVVM的重点内容

1.实现INotifyPropertyChanged接口

    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler? PropertyChanged;

        public void OnPropertyChanged([CallerMemberName] string name=null)
        {
            PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(name));
        }

        public void Set<T>(ref T field, object value, [CallerMemberName] string name="")
        {
            field= (T?)value!;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));            
        }
    }

2.实现ICommand接口以及事件转命令

  • 实现实现ICommand接口
	public class DelegateCommand : ICommand
    {
        public event EventHandler? CanExecuteChanged;

        public DelegateCommand(Action executeActionNoPara, Func<bool> canExcuteFuncNoPara = null!)
        {
            this.ExecuteActionNoPara = executeActionNoPara;
            this.CanExcuteFuncNoPara = canExcuteFuncNoPara;
        }

        public DelegateCommand(Action<object?> executeAction, Func<object?, bool> canExcuteFunc = null!)
        {
            this.ExecuteAction= executeAction;
            this.CanExcuteFunc = canExcuteFunc;
        }

        public bool CanExecute(object? parameter=null)
        {
            if (parameter==null)   return this.CanExcuteFuncNoPara == null ? true : this.CanExcuteFuncNoPara.Invoke();
            return this.CanExcuteFunc == null ? true : this.CanExcuteFunc.Invoke(parameter);
        }

        public void Execute(object? parameter = null)
        {
            if (parameter == null) this.ExecuteActionNoPara?.Invoke();
            else this.ExecuteAction?.Invoke(parameter);
        }

        public Action ExecuteActionNoPara { get; set; }
        public Func<bool> CanExcuteFuncNoPara { get; set; }

        public Action<object?> ExecuteAction { get; set; }
        public Func<object?,bool> CanExcuteFunc { get; set; }
    }
  • 事件转命令
    • 1 首先添加名为 Microsoft.Xaml.Behaviors.Wpf 的NuGet包
    • 2 然后在界面中引用 xmlns:i=“http://schemas.microsoft.com/xaml/behaviors”
    • 3 使用,具体使用方法如下:
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Background="Red">
    <i:Interaction.Triggers>
         <i:EventTrigger EventName="MouseDown">
             <i:InvokeCommandAction Command="{Binding MouseDownCommand}"></i:InvokeCommandAction>
         </i:EventTrigger>
    </i:Interaction.Triggers>
</StackPanel>

3.实现窗体间的交互与数据传递

这一块儿的内容,当前系列之前并没有介绍,在这里介绍一下。
假如现在有这样一个需求,点击用户列表中的某一项,我需要打开一个窗口查看该项的详情页,那么必定就会涉及,新开一个窗口,并且窗体将需要传递数据。
如果我们在ViewModel 中按照下面代码实现:

        private void ShowDetail()
        {
            UserDetailView view = new UserDetailView();
            //.....
            UserDetailView.Show();
        }

功能是可以实现,但是显然,不符合解耦的目的。MVVM的目的就是解耦,如果在ViewModel中操作View的内容,无疑又干回去!那我们应该去如何操作呢?定义一个专用于窗体间交互与数据传递的类,
窗体间需要做任何事情,都找"它"。

形如:

    public class WindowManager
    {
        private static Dictionary<string, Action<object>> _dir = new Dictionary<string, Action<object>>();
        public static void Register(string key,Action<object> action)
        {
            if (!string.IsNullOrEmpty(key)&&!_dir.ContainsKey(key))
            {
                _dir.Add(key,action);
            }
        }

        public static void DoAction(string key,object obj)
        {
            if (!string.IsNullOrEmpty(key) && _dir.ContainsKey(key))
            {
                _dir[key]?.Invoke(obj);
            }
        }
    }

当然,我们还可以根据项目对该类做完善和扩展。

4.页面切换时数据的处理

未完待续

5.特别说明

  • View中依赖属性需要绑定ViewModel中的属性
  • 注意绑定的是ViewModel中的属性,不是字段。
  • 注意为了实现View和Model的隔离,View是绑定ViewModel中属性,而不可以直接绑定Model层,Model可以为ViewModel提供数据模型,如我们常见场景Model中有个UserInfo类,然后再在ViewModel将UserInfo 申明为一个属性User,View会绑定ViewModel中User属性
  • 那么何时将属性设置在ViewModel中,何时将属性放在Model中供ViewModel使用呢?
    ①一般页面上展示集合的情况,都是需要将数据模型放在Model层,然后通过ViewModel申明为一个泛型集合来使用;
    ②在界面上有一些不同区域需要展示不同数据的情况,如,左边需要放用户数据,右边需要放订单数据或其他什么数据,就需要在Model中分别定义数据模型,然后ViewModel中使用;
    ③在少数情况下可以直接在属性申明在ViewModel中,而省去在Model中定义数据模型,这类情况一般就是该属性复用的地方极少,或者只有一两个零散的属性会在View中需要使用。
  • 在绑定集合的时候,若要设置动态绑定,以便集合中的插入或删除操作可以自动更新 UI,则集合必须实现 INotifyCollectionChanged 接口,WPF 提供 ObservableCollection 类,该类是公开 INotifyCollectionChanged 接口的数据集合的内置实现。如果还要实现集合每项对象属性值的变化通知到UI则还需要集合的数据对象实现INotifyCollectionChanged。
  • 解耦的根本在个人理解来看,就是加个"第三方代理商",有什么事情都找代理商,比如要将View和Model 解耦,就加了一个ViewModel用于两者的解耦。

结语

以上就是本文要介绍的内容,希望以上内容可以帮助到你,如文中有不对之处,还请批评指正。文章来源地址https://www.toymoban.com/news/detail-426073.html


到了这里,关于第六章:自建MVVM模式的简易项目框架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第六章、用户体验五要素之框架层解析(本文作用是通俗讲解,让你更容易理解)

            结构层定义产品运行形式,框架层则用于确定用什么样的功能或者形式来实现。在框架层,功能型和信息型产品都需要信息设计,不同的是功能型还需要界面设计,而信息型产品则是导航设计。         1、界面设计:如果涉及提供给用户做某些事的能力,那就是界

    2024年02月09日
    浏览(41)
  • 小程序项目学习--第六章:项目实战二、推荐歌曲-歌单展示-巅峰榜-歌单详情-页面优化

    推荐歌曲的数据获取的实现步骤 0.封装对应请求接口方法 1.封装和调用请求函数的方法 2.将数据放到data中 3.展示数据 针对每个item,我们可以继续封装成一个小组件song-item-v1 封装一个小组件步骤 1.创建组件页面 song-item-v1 2.在使用组件的地方注册组件,使用组件 3.通过propert

    2024年02月09日
    浏览(38)
  • WPF 使用MVVM框架创建一个项目

    步骤如下: 1、打开Visual Studio 2017(或其他版本),选择新建项目 2、选择WPF应用(.Net Framework),同时给项目命名,并选择项目存放路径,最后点击确定 3、右键点击解决方案名称,点击“管理NuGet程序包”,点击浏览,在输入框中输入mvvmlight,点击MvvmLight进行安装,安装过程

    2024年02月05日
    浏览(65)
  • 安卓基础巩固(四):设计原则、安卓主流技术框架MVC/MVP/MVVM、设计模式

    模块化功能:使得程序模块化,即内部高聚合,模块之间低耦合 提高开发效率:开发人员只需要专注于一点(视图显示、业务逻辑、数据处理) 提高测试效率:后期测试时可以迅速根据报错反馈,定位到问题出现的位置。 六大设计原则是设计模式的理论,设计模式是设计原

    2024年02月06日
    浏览(53)
  • WPF 项目中 MVVM模式 的简单例子说明

    MVVM 是 Model view viewModel 的简写。MVVM模式有助于将应用程序的业务和表示逻辑与用户界面清晰分离。 几个概念的说明: model :数据,界面中需要的数据,最好不要加逻辑代码 view : 视图就是用户看到的UI结构 xaml 文件 viewModel : 业务逻辑代码 绑定器:声明性数据和命令绑定隐含在

    2024年02月11日
    浏览(30)
  • 第六章 Linux 磁盘管理

    如果我们想在系统中增加一块硬盘用于数据存取,那么大概需要以下步骤: 目的,一是为了分割硬盘空间方便管理,更重要的是让各个分区都基本独立开来,这样如果某个区发生问题,至少不会直接影响到其他分区。 举例:如果把一块磁盘比喻成一大块地,那么对磁盘进行

    2024年02月04日
    浏览(54)
  • 第六章 游标

    本文内容较短,我们只是为了更容易的实现b树,简单地重构一下。 我们将添加一个Cursor 表示表中对象的位置。Cursor应提供如下几个方面的能力: 在表的开头创建游标 在表的末尾创建游标 访问=游标指向的行 将游标前进到下一行 这是本文我们要实现的能力,后面我们还希望

    2024年02月15日
    浏览(35)
  • Scala(第六章 面向对象)

    1、 Scala的面向对象思想和Java的面向对象思想和概念是一致的。 2、Scala中语法和Java不同,补充了更多的功能。 1)基本语法 1 2)Scala包的三大作用(和Java一样) 1、区分相同名字的类 2、当类很多时,可以很好的管理类 3、控制访问范围 6.1.1 包的命名 1)命名规则 只能包含数

    2024年02月13日
    浏览(46)
  • 数据结构:第六章 图

    ps:图不可以为空图。 对于图中的边,两头必须要有结点。 边集是可以没有的,如上图最右边。 关于无向图和有向图的应用如下 比如你微信里的好友关系,你要和一个人建立关系(也就是图的两个结点连上),你只需要加1次就可以了,也不需要你加我,我还要加你。 具体

    2024年02月14日
    浏览(44)
  • 第六章 集合引用类型

    6.1 Object         到目前为止,大多数引用值的示例使用的是Object类型。Object是ECMAScript中最常用的类型之一。虽然Object的实例没有多少功能,但很适合存储和在应用程序间交换数据。         显式地创建Object的实例有两种方式。第一种是使用new操作符和Object构造函数,

    2024年01月18日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包