数据绑定和 MVVM

您所在的位置:网站首页 点击按钮触发函数 数据绑定和 MVVM

数据绑定和 MVVM

2024-07-01 10:08:52| 来源: 网络整理| 查看: 265

数据绑定和 MVVM 项目 05/05/2023

浏览示例

Model-View-ViewModel (MVVM) 模式强制在三个软件层之间强制分离:称为视图的 XAML 用户界面、基础数据(称为模型)和视图与模型之间的中介(称为 viewmodel)。 视图和 viewmodel 通常通过 XAML 中定义的数据绑定进行连接。 BindingContext视图的 通常是 viewmodel 的实例。

重要

.NET 多平台应用 UI (.NET MAUI) 封送对 UI 线程的绑定更新。 使用 MVVM 时,可以使用 .NET MAUI 的绑定引擎从任何线程更新数据绑定的 viewmodel 属性,从而将更新引入 UI 线程。

简单 MVVM

在 XAML 标记扩展 中,你已了解如何定义新的 XML 命名空间声明,以允许 XAML 文件引用其他程序集中的类。 以下示例使用 x:Static 标记扩展从 命名空间中的System静态DateTime.Now属性获取当前日期和时间:

在此示例中,检索 DateTime 到的值设置为 BindingContext 上的 StackLayout。 在元素上设置 BindingContext 时,它将由该元素的所有子元素继承。 这意味着 的所有子级 StackLayout 都具有相同的 BindingContext,并且它们可以包含到该对象的属性的绑定:

但是,问题是在构造和初始化页面时,日期和时间设置一次,并且永远不会更改。

XAML 页面可以显示始终显示当前时间的时钟,但它需要其他代码。 当从视觉对象和基础数据之间的属性绑定数据时,MVVM 模式是 .NET MAUI 应用的自然选择。 在考虑 MVVM 时,模型和 viewmodel 是完全用代码编写的类。 视图通常是一个 XAML 文件,它通过数据绑定引用 viewmodel 中定义的属性。 在 MVVM 中,模型对 viewmodel 不了解,viewmodel 对视图无知。 但是,通常会将 viewmodel 公开的类型定制为与 UI 关联的类型。

注意

在 MVVM 的简单示例中(如此处所示的示例)中,通常根本没有模型,并且模式仅涉及与数据绑定链接的视图和视图模型。

以下示例演示时钟的 viewmodel,其中包含一个名为 DateTime 的单个属性,该属性每秒更新一次:

using System.ComponentModel; using System.Runtime.CompilerServices; namespace XamlSamples; class ClockViewModel: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private DateTime _dateTime; private Timer _timer; public DateTime DateTime { get => _dateTime; set { if (_dateTime != value) { _dateTime = value; OnPropertyChanged(); // reports this property } } } public ClockViewModel() { this.DateTime = DateTime.Now; // Update the DateTime property every second. _timer = new Timer(new TimerCallback((s) => this.DateTime = DateTime.Now), null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); } ~ClockViewModel() => _timer.Dispose(); public void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }

Viewmodels 通常实现 INotifyPropertyChanged 接口,该接口使类能够在其属性之一发生更改时引发 PropertyChanged 事件。 .NET MAUI 中的数据绑定机制将处理程序附加到此 PropertyChanged 事件,以便在属性更改时收到通知,并使用新值保持目标更新。 在前面的代码示例中 OnPropertyChanged ,方法处理引发 事件,同时自动确定属性源名称: DateTime。

以下示例演示使用 的 ClockViewModelXAML:

在此示例中, ClockViewModel 设置为 BindingContext using 属性元素标记的 ContentPage 。 或者,代码隐藏文件可以实例化 viewmodel。

Binding的 属性Label上的Text标记扩展设置 属性的格式DateTime。 以下屏幕截图显示了结果:

此外,还可以通过用句点分隔属性来访问 viewmodel 属性的各个 DateTime 属性:

交互式 MVVM

MVVM 通常用于基于基础数据模型的交互式视图的双向数据绑定。

以下示例演示 HslViewModel 将值转换为 ColorHue、 Saturation和 Luminosity 值的 ,然后再次返回 :

using System.ComponentModel; using System.Runtime.CompilerServices; namespace XamlSamples; class HslViewModel: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private float _hue, _saturation, _luminosity; private Color _color; public float Hue { get => _hue; set { if (_hue != value) Color = Color.FromHsla(value, _saturation, _luminosity); } } public float Saturation { get => _saturation; set { if (_saturation != value) Color = Color.FromHsla(_hue, value, _luminosity); } } public float Luminosity { get => _luminosity; set { if (_luminosity != value) Color = Color.FromHsla(_hue, _saturation, value); } } public Color Color { get => _color; set { if (_color != value) { _color = value; _hue = _color.GetHue(); _saturation = _color.GetSaturation(); _luminosity = _color.GetLuminosity(); OnPropertyChanged("Hue"); OnPropertyChanged("Saturation"); OnPropertyChanged("Luminosity"); OnPropertyChanged(); // reports this property } } } public void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }

在此示例中,对 、 和 属性的Hue更改会导致Color属性发生更改,而对 属性的更改Color会导致其他三个属性发生Luminosity更改。 Saturation 这可能看起来像一个无限循环,不同之处在于,除非属性已更改,否则 viewmodel 不会调用 PropertyChanged 事件。

下面的 XAML 示例包含一个 BoxView ,其Color属性绑定到 Color viewmodel 的 属性,以及绑定到 、 Saturation和 属性的Hue三Slider个视图和Luminosity三个Label视图:

每个 Label 上的绑定是默认 OneWay的 。 它只需要显示值。 但是,每个 Slider 绑定的默认绑定是 TwoWay。 这允许 Slider 从 viewmodel 初始化 。 实例化 viewmodel 时,其 Color 属性设置为 Aqua。 中的 Slider 更改为 viewmodel 中的 属性设置新值,然后计算新颜色:

命令

有时,通过要求用户启动影响 viewmodel 中某些对象的命令,应用的需求超出了属性绑定的范围。 这些命令通常通过点击按钮或手指敲击触发信号,往往是以下两个事件的处理程序中的代码隐藏文件中处理它们:Button 的 Clicked 事件或 TapGestureRecognizer 的 Tapped 事件。

命令接口提供了另一种实现命令的方法,这种方法更适合 MVVM 体系结构。 viewmodel 可以包含命令,这些命令是针对视图中的特定活动(例如 Button 单击)而执行的方法。 在这些命令和 Button 之间定义了数据绑定。

为了允许 在 和 viewmodel 之间进行 Button 数据绑定,定义了 Button 两个属性:

Command 类型的 System.Windows.Input.ICommand CommandParameter 类型的 Object

注意

许多其他控件还定义 Command 和 CommandParameter 属性。

接口 ICommand 在 System.Windows.Input 命名空间中定义,由两个方法和一个事件组成:

void Execute(object arg) bool CanExecute(object arg) event EventHandler CanExecuteChanged

viewmodel 可以定义 类型的 ICommand属性。 然后,可以将这些属性绑定到 Command 彼此 Button 或其他元素的 属性,或者可能绑定到实现此接口的自定义视图。 可以选择设置 CommandParameter 属性,以标识绑定到此 viewmodel 属性的单个 Button 对象 (或其他元素) 。 在内部,ButtonExecute每当用户点击 Button时调用 方法,并将 Execute 传递给方法其 CommandParameter。

方法和CanExecuteCanExecuteChanged事件用于点击当前可能无效的情况Button,在这种情况下, Button 应禁用自身。 Button首次设置 属性时Command以及每当引发事件时调用 CanExecuteCanExecuteChanged 。 如果 CanExecute 返回 false,则 Button 禁用本身,并且不会生成 Execute 调用。

可以使用 Command .NET MAUI 中包含的 或 Command 类来实现 ICommand 接口。 这两个类定义了多个构造函数和一个 ChangeCanExecute 方法,viewmodel 可以调用该方法来强制 Command 对象引发 CanExecuteChanged 事件。

以下示例演示用于输入电话号码的简单键盘的 viewmodel:

using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; namespace XamlSamples; class KeypadViewModel: INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _inputString = ""; private string _displayText = ""; private char[] _specialChars = { '*', '#' }; public ICommand AddCharCommand { get; private set; } public ICommand DeleteCharCommand { get; private set; } public string InputString { get => _inputString; private set { if (_inputString != value) { _inputString = value; OnPropertyChanged(); DisplayText = FormatText(_inputString); // Perhaps the delete button must be enabled/disabled. ((Command)DeleteCharCommand).ChangeCanExecute(); } } } public string DisplayText { get => _displayText; private set { if (_displayText != value) { _displayText = value; OnPropertyChanged(); } } } public KeypadViewModel() { // Command to add the key to the input string AddCharCommand = new Command((key) => InputString += key); // Command to delete a character from the input string when allowed DeleteCharCommand = new Command( // Command will strip a character from the input string () => InputString = InputString.Substring(0, InputString.Length - 1), // CanExecute is processed here to return true when there's something to delete () => InputString.Length > 0 ); } string FormatText(string str) { bool hasNonNumbers = str.IndexOfAny(_specialChars) != -1; string formatted = str; // Format the string based on the type of data and the length if (hasNonNumbers || str.Length < 4 || str.Length > 10) { // Special characters exist, or the string is too small or large for special formatting // Do nothing } else if (str.Length < 8) formatted = string.Format("{0}-{1}", str.Substring(0, 3), str.Substring(3)); else formatted = string.Format("({0}) {1}-{2}", str.Substring(0, 3), str.Substring(3, 3), str.Substring(6)); return formatted; } public void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }

在此示例中, Execute 命令的 和 CanExecute 方法在构造函数中定义为 lambda 函数。 viewmodel 假定 AddCharCommand 属性绑定到 Command 多个按钮的 属性, (或其他任何具有命令接口的控件) ,每个按钮都由 CommandParameter标识。 这些按钮向属性添加字符 InputString ,然后该属性的格式设置为属性的 DisplayText 电话号码。 还有一个名为 类型的 ICommand 第二个 DeleteCharCommand属性。 这绑定到后退间距按钮,但如果没有要删除的字符,则应禁用该按钮。

以下示例演示使用 的 KeypadViewModelXAML:

在此示例中,第 Command 一个 Button 绑定到 的 DeleteCharCommand属性。 其他按钮绑定到 AddCharCommand ,其 CommandParameter 与 上 Button显示的字符相同:



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭