博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第十八章:MVVM(三)
阅读量:6256 次
发布时间:2019-06-22

本文共 4340 字,大约阅读时间需要 14 分钟。

ViewModel时钟

假设您正在编写需要访问当前日期和时间的程序,并且您希望通过数据绑定来使用该信息。 .NET基类库通过DateTime结构提供日期和时间信息。要获取当前日期和时间,只需访问DateTime.Now属性。这是编写时钟应用程序的习惯方式。
但是出于数据绑定的目的,DateTime有一个严重的缺陷:它只提供静态信息,在日期或时间发生变化时没有通知。
在MVVM的上下文中,DateTime结构可能有资格作为模型,因为DateTime提供了我们需要的所有数据,但没有提供有利于数据绑定的形式。编写一个使用DateTime但在日期或时间发生变化时提供通知的ViewModel是必要的。
Xamarin.FormsBook.Toolkit库包含如下所示的DateTimeViewModel类。该类只有一个属性,名为DateTime,类型为DateTime,但由于在Device.StartTimer回调中频繁调用DateTime.Now,此属性会动态更改。
请注意,DateTimeViewModel类基于INotifyPropertyChanged接口,并包含用于定义此接口的System.ComponentModel命名空间的using指令。要实现此接口,该类定义名为PropertyChanged的公共事件。
注意:在类中定义PropertyChanged事件非常容易,而没有明确指定该类实现INotifyPropertyChanged!如果您没有明确指定该类基于INotifyPropertyChanged接口,则将忽略通知:

using System;using System.ComponentModel;using Xamarin.Forms;namespace Xamarin.FormsBook.Toolkit{    public class DateTimeViewModel : INotifyPropertyChanged    {        DateTime dateTime = DateTime.Now;        public event PropertyChangedEventHandler PropertyChanged;        public DateTimeViewModel()        {            Device.StartTimer(TimeSpan.FromMilliseconds(15), OnTimerTick);        }        bool OnTimerTick()        {            DateTime = DateTime.Now;            return true;        }        public DateTime DateTime        {            private set            {                if (dateTime != value)                {                    dateTime = value;                    // Fire the event.                    PropertyChangedEventHandler handler = PropertyChanged;                    if (handler != null)                    {                        handler(this, new PropertyChangedEventArgs("DateTime"));                    }                }            }            get            {                return dateTime;            }        }    }}

此类中唯一的公共属性称为DateTime类型的DateTime,它与名为dateTime的专用支持字段相关联。 ViewModels中的公共属性通常具有私有支持字段。 DateTime属性的set访问器对于类是私有的,并且它从计时器回调每15毫秒更新一次。

除此之外,set访问器以非常标准的方式构造用于ViewModel:它首先检查设置为属性的值是否与dateTime支持字段不同。 如果没有,它将从传入值设置该支持字段,并使用属性的名称触发PropertyChanged处理程序。 如果仅将属性设置为其现有值,则触发PropertyChanged处理程序被认为是非常糟糕的做法,甚至可能导致在双向绑定中涉及无限循环的递归属性设置的问题。
这是触发事件的set访问器中的代码:

PropertyChangedEventHandler handler = PropertyChanged;if (handler != null){    handler(this, new PropertyChangedEventArgs("DateTime"));}

这种形式比这样的代码更好,它不会将处理程序保存在单独的变量中:

if (PropertyChanged != null){    PropertyChanged(this, new PropertyChangedEventArgs("DateTime"));}

在多线程环境中,PropertyChanged处理程序可能在检查空值的if语句和事件的实际触发之间分离。 将处理程序保存在单独的变量中可防止导致问题,因此即使您尚未在多线程环境中工作,也应采用这种习惯。

get访问器只返回dateTime支持字段。
MvvmClock程序演示了DateTimeViewModel类如何通过数据绑定向用户界面提供更新的日期和时间信息:

页面的Resources部分实例化DateTimeViewModel,还为Label定义了一个隐式Style。

六个Label元素中的第一个将其Text属性设置为涉及实际.NET DateTime结构的Binding对象。该绑定的Source属性是一个x:Static标记扩展,它引用静态DateTime.Now属性以获取程序首次开始运行时的日期和时间。此绑定不需要路径。 “F”格式规范适用于完整日期/时间模式,具有日期和时间字符串的长版本。虽然此Label显示程序启动的日期和时间,但它永远不会更新。
最后的四个数据绑定将被更新。在这些数据绑定中,Source属性设置为引用DateTimeViewModel对象的StaticResource标记扩展。 Path设置为该ViewModel的DateTime属性的各种子属性。在幕后,绑定基础结构在DateTimeViewModel中的PropertyChanged事件上附加处理程序。此处理程序检查DateTime属性中的更改,并在该属性更改时更新Label的Text属性。
除了InitializeComponent调用之外,代码隐藏文件是空的。最后四个标签的数据绑定显示更新时间,其更新速度与视频刷新率一样快:
2018_10_10_130902
通过将StackLayout的BindingContext属性设置为引用ViewModel的StaticResource标记扩展,可以简化此XAML文件中的标记。 BindingContext通过可视树传播,以便您可以删除最后四个Label元素上的Source设置:

第一个Label上的Binding覆盖了BindingContext及其自己的Source设置。

您甚至可以从ResourceDictionary中删除DateTimeViewModel项,并在BindingContext属性元素标记之间的StackLayout中实例化它:

或者,您可以将StackLayout的BindingContext属性设置为包含的Binding

DateTime属性。 然后BindingContext成为DateTime值,它允许单独的绑定简单地引用.NET DateTime结构的属性:

你可能会怀疑这会起作用! 在幕后,数据绑定通常会安装PropertyChanged事件处理程序并监视正在更改的特定属性,但在这种情况下它不能,因为数据绑定的源是DateTime值,而DateTime不实现INotifyPropertyChanged。 但是,这些Label元素的BindingContext随着ViewModel中DateTime属性的每次更改而更改,因此绑定基础结构此时会访问这些属性的新值。

由于Text属性上的单个绑定在长度和复杂性方面都有所减少,因此您可以删除Path属性名称并将所有内容放在一行上,并且不会混淆任何内容:

在本书的未来计划中,个人绑定将尽可能简短和优雅。

转载地址:http://nwisa.baihongyu.com/

你可能感兴趣的文章
Java 读取 .properties 配置文件
查看>>
IntelliJ IDEA 12 key from twitter
查看>>
css
查看>>
装饰设计模式
查看>>
《Linux内核原理与分析》第八周作业
查看>>
企业级工作流解决方案(二)--微服务总体介绍
查看>>
Bonbo Git Server
查看>>
取消文件默认打开方式
查看>>
JVM 调试工具
查看>>
Linux C 语言 获取系统时间信息
查看>>
pku 1182 食物链
查看>>
echarts使用笔记四:双Y轴
查看>>
删除操作系统服务(Delete OS Service)
查看>>
effective JAVA 阅读笔记。
查看>>
Core Data: 多线程大量数据同步
查看>>
二分法查找
查看>>
浏览器推荐 --- 搜狗浏览器
查看>>
感冒 类型
查看>>
DataGridView 清空数据
查看>>
iis网站发布相关问题
查看>>