Xamarin模型-视图-视图模型模式(MVVM)示例解释

本文概述

  • 介绍
  • MVVM模式
  • 视图
  • 视图模型
  • 模型
  • 将视图模型连接到视图
  • 总结
介绍 MVVM代表Model-View-ViewModel。 MVVM代表将代码分为与领域相关的数据(模型)和数据表示形式(视图), 最后是程序的逻辑(称为业务逻辑)(视图模型)。 ViewModel的职责是可见性。
Xamarin.Forms开发人员需要在XAML中创建一个用户界面, 然后在用户界面上的操作后面添加代码。随着应用程序的修改以及规模和范围的扩大, 出现了维护问题。这些问题包括UI控件和业务逻辑之间的紧密耦合, 这增加了UI修改的成本, 并且将面临代码的单元测试的困难。
Model-View-ViewModel(MVVM)模式有助于将应用程序的业务和表示逻辑与其用户界面分开。在应用程序逻辑和UI之间保持清晰的隔离有助于解决不同的问题, 并使应用程序更易于测试, 维护和发展。它还可以提高代码重用的机会, 并在我们开发应用程序的各个部分时使开发人员和UI设计师可以轻松地进行协作。
MVVM模式 MVVM包含三个核心组件:模型, 视图和视图模型。每个都有不同的功能。
在这里, 我们将显示三个组件之间的不同关系:
Xamarin模型-视图-视图模型模式(MVVM)示例解释

文章图片
关系
此外, 要了解每个组件的职责, 了解它们如何相互影响也很重要。
在较高级别上, 视图” 知道” 视图模型, 而视图模型知道该模型, 但是该模型不知道视图模型, 而视图模型也不知道View。因此, 视图模型将视图与模型隔离开, 并允许模型独立于视图进行演化。
MVVM模式的好处
使用MVVM模式的好处是:
  • 如果有一个加密当前业务逻辑的现有模型实现, 则更改它可能很困难或有风险。
  • 在这种情况下, 视图模型充当模型类的适配器, 使我们能够避免对模型代码进行任何重大更改。
  • 开发人员无需使用视图即可创建视觉模型和模型的单元测试。视图模型的单元测试可以利用与视图相同的功能。
  • 如果View是在XAML中实现的, 则无需触摸代码即可重新设计应用程序的UI。因此, 新版本的View应该可以与现有的View模型一起使用。
  • 设计人员和开发人员可以在开发过程中独立并同时处理其组件
  • 设计人员可以专注于可视化, 而开发人员可以处理可视化模型和模型组件。
视图 视图负责定义结构的布局和屏幕的外观。每个视图都是在XAML中定义的;它包含有限的代码, 其中不包含业务逻辑。在某些情况下, 隐藏代码可能会提供UI逻辑, 以实现视觉行为, 这在XAML中很难表达, 例如动画。
在Xamarin.Forms应用程序中, “ 视图” 是Page类型或ContentView派生的类。视图也可以由数据模板表示, 该模板指定用于在显示对象时可视化该对象的UI元素。数据模板作为一个视图, 没有任何代码后置, 并且被设计为绑定到特定的视图模型类型。存在用于在视图模型上执行代码以与视图交互的多个选项, 例如单击按钮或选择项目。如果控件支持命令, 则可以将控件的命令数据绑定到视图模型上的Icommand属性。当调用控件的命令时, 将执行视图模型中的代码。除命令外, 行为还可以附加到视图中的对象, 并可以侦听要调用的命令或引发的事件。然后, 在该响应中, 行为可以在视图模型上调用Icommand或在视图模型上调用方法。
视图模型 视图模型实现视图可以绑定数据的属性和命令, 并通过更改通知事件通知视图任何要更改的状态。视图模型的命令和属性定义了UI的功能, 但是View决定了如何显示功能。
View Model还负责协调View与所需的任何模型类的交互。视图模型可能选择直接将模型类公开给视图, 以便视图中的控件可以将数据直接绑定到它们。在这种情况下, 需要设计模型类以支持数据绑定和更改通知事件。每个视图模型都以易于使用的形式提供数据。视图模型有时会执行数据转换。将转换放入视图模型是一个好主意, 因为它提供了View可以绑定到的属性。例如, 视图模型可以合并两个属性的值, 以使其更易于由视图显示。
为了使视图模型参与与视图的双向数据绑定, 其属性必须引发PropertyChanged事件。
视图模型通过实现INotifyPropertyChanged接口并在属性更改时扩展PropertyChanged事件来满足此要求。
对于集合, 提供了对视图友好的ObjervableCollection < T> 。此集合实现集合更改通知, 从而使开发人员不必在集合上实现INotifyCollectionChanged接口。
模型 模型类是封装应用程序数据的非可视类。因此, 可以将模型视为代表应用程序的域模型, 该模型通常包括数据模型以及业务和验证逻辑。
模型对象的示例包括数据传输对象(DTO), 普通旧CLR对象(PO??CO), 以及生成的实体和代理对象。模型类通常与服务或存储库结合使用, 后者封装了数据访问和缓存。
将视图模型连接到视图 可以使用Xamarin.Forms的数据绑定功能将视图模型链接到视图。
可以使用几种方法来构造视图和视图模型, 并在运行时添加它们。
这些方法分为两类, 称为视图优先组合和视图模型优先组合。在” 视图优先” 构图和” 视图模型优先” 构图之间选择偏好和复杂性的问题。但是, 所有方法都具有相同的目标, 即将View的视图模型分配给BindingContext属性。
查看第一个构图
这种方法的好处是, 由于视图模型不依赖于视图本身, 因此可以轻松构建松耦合的, 可单元测试的应用程序。通过遵循应用程序的外观结构, 而不是跟踪代码的执行过程来了解类的创建和关联方式, 很容易理解应用程序的结构。而且, Viewfirst结构与Xamarin保持一致。表单导航系统负责在导航发生时构造页面, 这使得视图模型首先组成复杂并且与平台不对齐。
查看模型第一个成分
视图模型优先构图对于某些开发人员而言更为自然。由于视图创建可以被抽象化, 并允许他们专注于应用程序的逻辑非UI结构。而且, 它可以使视图模型可以由其他视图模型创建。但是, 这种方法通常很复杂, 可能很难理解应用程序的各个部分是如何创建和关联的。
这是将视图模型连接到视图的方法。
声明式创建视图模型
View的最直接方法是在XAML中以声明方式初始化其相应的视图模型。构造视图时, 还将构造相应的视图模型对象。
我们将通过以下代码讨论这种方法:
< ContentPage ...xmlns:local="clr-namespace:eShop"> < ContentPage.BindingContext> < local:LoginViewModel /> < /ContentPage.BindingContext> ... < /ContentPage>

创建ContentPage时, 将自动构造LoginViewModel的实例并将其设置为视图的BindingContext。
这样做的好处是它很简单, 但是它的缺点是需要在视图模型中使用默认构造函数。
以编程方式创建视图模型
视图可以在代码隐藏文件中包含代码, 从而导致将视图模型分配给其BindingContext属性。这通常在View的构造函数中完成, 如以下代码所示:
public LoginView() { InitializeComponent(); BindingContext = new LoginViewModel(navigation service); }

视图代码背后的视图模型的编程构造和分配具有简单的优点。这种方法的缺点是, 视图需要为视图模型提供任何必需的依赖关系。
创建定义为数据模板的视图
可以将视图定义为数据模板, 并将其与视图模型类型相关联。数据模板可以定义为资源, 也可以在控件中内联定义, 以显示视图模型。控件的内容是视图模型实例, 并且数据模板用于直观地表示它。此技术是一种情况的示例, 其中视图模型首先初始化, 然后创建视图。
使用视图模型定位器自动创建视图模型
视图模型定位器是一个自定义类, 用于管理视图模型的初始化及其与视图的关联。在EShopOnContainers移动应用程序中, ViewModelLocator类具有附加属性AutoWireViewModel, 该属性用于将视图连接到视图模型。在视图的XAML中, 此附加属性设置为true, 以指示视图模型应自动连接到以下代码所示的视图:
viewModelBase:ViewModelLocator.AutoWireViewModel="true"

AutoWireViewModel属性是一个可绑定属性, 其初始化为false, 并且当值更改时, 将调用OnAutoWireViewModelChanged事件处理程序。此方法解析视图的视图模型。
例:
private static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue) { var view = bindable as Element; if (view == null) { return; }var viewType = view.GetType(); var viewName = viewType.FullName.Replace(".Views.", ".ViewModels."); var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName; var viewModelName = string.Format( CultureInfo.InvariantCulture, "{0}Model, {1}", viewName, viewAssemblyName); var viewModelType = Type.GetType(viewModelName); if (viewModelType == null) { return; } var viewModel = _container.Resolve(viewModelType); view.BindingContext = viewModel; }

OnAutoWireViewModelChanged方法尝试使用基于约定的方法来解析视图模型。该约定假定:
  • 视图模型与视图类型在同一装配中。
  • 视图位于-views子命名空间中。
  • 视图模型位于-Viewmodels子命名空间中。
  • 视图模型名称与视图名称相对应, 并以” ViewModel” 结尾。
最后, OnAutoWireViewModelChanged方法将视图类型的BindingContext设置为解析的视图模型类型, 以确定有关视图模型类型的更多信息。这种方法的优势在于, 应用程序具有单个类, 该类负责视图模型的初始化及其与视图的连接。
总结 Model-View-ViewModel(MVVM)模式有助于将应用程序的业务和表示逻辑与其用户界面(UI)分开。在应用程序逻辑和UI之间保持清晰的隔离, 这有助于解决众多开发问题, 并使应用程序更易于测试, 维护和发展。它还可以提高代码重用的机会, 并允许开发人员和UI设计师在我们开发应用程序的各个部分时轻松地进行协作。
【Xamarin模型-视图-视图模型模式(MVVM)示例解释】通过使用MVVM模式, 应用程序的UI, 基础表示和业务逻辑分为三类。类是View, 它封装了表示逻辑和状态, 而模型则封装了业务逻辑和数据。

    推荐阅读