WPF12-MVVM

news/2025/2/28 6:24:55/

目录

  • 1. 什么是MVVM
  • 2. 实现简单MVVM
    • 2.1. Part 1
    • 2.2. Part 2

1. 什么是MVVM

MVVMModel-View-ViewModel 的缩写,是一种用于构建用户界面的设计模式,是一种简化用户界面的事件驱动编程方式。

MVVM 的目标是实现用户界面和业务逻辑之间的彻底分离,以便更好地管理和维护应用程序,并提供更好的可测试性和可扩展性。

MVVM 模式包含以下三个核心组件:

Model(模型):Model 代表应用程序的数据和业务逻辑。它负责存储和管理数据,并且通常不包含任何与用户界面相关的代码。Model 可以是数据实体、数据库访问类、服务类等。

View(视图):View 是用户界面的可视化表示,通常由 XAML 文件定义。它负责展示数据给用户,并捕获用户输入。View 并不处理业务逻辑,而是通过绑定和命令将用户操作传递给 ViewModel。

ViewModel(视图模型):ViewModel 是 View 和 Model 之间的桥梁,负责处理 View 与 Model 之间的交互。它将 Model 中的数据转换为 View 所需的数据,并处理用户输入、命令和其他交互逻辑。ViewModel 通常实现了 INotifyPropertyChanged 接口,用于通知 View 当数据发生变化时进行更新。

文章配图

MVVM 的基本原则是让 View 和 Model 完全解耦,它们之间通过 ViewModel 进行通信。View 通过数据绑定将 ViewModel 中的数据展示给用户,通过命令绑定将用户的操作传递给 ViewModel。ViewModel则通过数据绑定和命令绑定将用户输入转换为对 Model 的操作,从而实现业务逻辑的处理。

回到 WPF 里,View就是用xaml描绘的页面,负责与用户交互,响应用户操作,展示数据给用户;ViewModel负责收集需要绑定的数据和命令,通过 View 的 DataContext 属性绑定到 View,同时处理UI逻辑;Model 就作为系统中的对象,包含数据对象。

一个 View 对应一个 ViewModel ,一个 ViewModel 可以聚合多个 Model,ViewModel 可以对应多个 View,在 MVVM 下,所有事件和动作都转换成命令,如按钮的点击操作,不在是触发点击事件,而是绑定到命令,由命令去执行对应的逻辑。

MVVM 模式的优势包括:

分离关注点:MVVM 将用户界面逻辑和业务逻辑彻底分开,使代码结构更清晰,易于理解和维护。

可测试性:由于 View 和 ViewModel 之间的解耦,可以更轻松地对 ViewModel 进行单元测试,而无需涉及到用户界面的操作。

可扩展性:MVVM 支持模块化开发,不同的 View 和 ViewModel 可以独立开发和组合,使应用程序更易于扩展。

可重用性:ViewModel 可以与不同的 View进行重用,从而减少了重复编写代码的工作。

2. 实现简单MVVM

2.1. Part 1


<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"xmlns:local="clr-namespace:WpfApp1"Title="MVVM Demo" Height="450" Width="800"><Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" DataContext="{x:Static sys:DateTime.Now}"><TextBlock Text="{Binding Year, StringFormat='The year is {0}'}" /><TextBlock Text="{Binding StringFormat='The month is {0:MMMM}'}" /><TextBlock Text="{Binding Day, StringFormat='The day is {0}'}" /><TextBlock Text="{Binding StringFormat='The time is {0:T}'}" /></StackPanel></Grid>
</Window>

这段 Xaml 在 StackPanel 的 DataContext 中设置了一个绑定到当前日期和时间的 DateTime 对象,然后通过数据绑定将 DateTime 对象的各个属性显示在不同的子元素 TextBlock 中,同时对显示内容进行了格式化。

运行程序,文本中的日期和时间只会在构造和初始化的时候设置一次,不会随时间的变化而变化。

文章配图

2.2. Part 2

上面的页面写出来显然是没有意义的,我们想让它实时显示当前时间,这就需要有个东西在时间发生变化时一直更新页面上的时间,这个过程一般会通过后台代码完成,当然可以通过一个 Timer 搞定,但就和这篇文章的内容没关系了,用 MVVM 的模式怎么实现呢?

首先从 MVVM 三部分来看,View 就是标题为MVVM Demo的窗体,Model 是 DateTime 对象,需要 ViewModel 来处理时间数据同时通知页面响应更改。

创建一个ClockViewModel.cs类:

public 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();}}}public ClockViewModel(){DateTime = DateTime.Now;_timer = new Timer(new TimerCallback((s) => DateTime = DateTime.Now),null, TimeSpan.Zero, TimeSpan.FromSeconds(1));}~ClockViewModel() =>_timer.Dispose();public void OnPropertyChanged([CallerMemberName] string name = ""){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));}}

ClockViewModel 类实现了 INotifyPropertyChanged 接口,并通过 Timer 定时更新时间并触发属性更改通知,提供实时的系统时间。完成 ViewModel 部分以后,将 ViewModel 绑定到视图 View - MainWindow 上:


<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:sys="clr-namespace:System;assembly=mscorlib"xmlns:local="clr-namespace:WpfApp1"Title="MVVM Demo" Height="450" Width="800"><Window.DataContext><local:ClockViewModel /></Window.DataContext><Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" DataContext="{x:Static sys:DateTime.Now}"><TextBlock Text="{Binding Year, StringFormat='The year is {0}'}" /><TextBlock Text="{Binding StringFormat='The month is {0:MMMM}'}" /><TextBlock Text="{Binding Day, StringFormat='The day is {0}'}" /><TextBlock Text="{Binding StringFormat='The time is {0:T}'}" /></StackPanel><StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"><TextBlock Text="{Binding DateTime, StringFormat='The time is {0:T}'}" /></StackPanel></Grid>
</Window>

这样就可以得到一个 MVVM 模式下的时钟了:

在这里插入图片描述


http://www.ppmy.cn/news/1575431.html

相关文章

DeepSeek中的MLA技术

大模型推理的两个阶段&#xff1a;prefill和decode prefill阶段处理整个输入序列&#xff0c;并生成第一个输出token&#xff0c;并初始化KV cachedecode阶段则逐个生成后续的tokens KV cache 无KV cache的推理过程&#xff1a;每次生成新token时&#xff0c;需要将整个历史序列…

专题一和为s的两个数字

1.题目 题目分析&#xff1a; 在给定的数组中&#xff0c;找到俩个数字&#xff0c;且这两个数字的和与给定的target相等就行&#xff0c;可能会有很多组&#xff0c;但只要返回一组就可以。 2.算法原理 方法一&#xff1a; 暴力枚举法&#xff0c;通过俩层循环&#xff0c;…

【QT】QLinearGradient 线性渐变类简单使用教程

目录 0.简介 1&#xff09;qtDesigner中 2&#xff09;实际执行 1.功能详述 3.举一反三的样式 0.简介 QLinearGradient 是 Qt 框架中的一个类&#xff0c;用于定义线性渐变效果&#xff08;通过样式表设置&#xff09;。它可以用来填充形状、背景或其他图形元素&#xff0…

零基础学习OpenGL(一)创建一个窗口

基于 ubuntu 系统&#xff0c;设置基础环境。 #!/usr/bin/env bashsudo apt-get update# 安装基础编译软件 sudo apt-get -y install gcc g cmake git# 安装编译 glfw 依赖的软件 sudo apt-get -y install libwayland-dev libx11-dev libxcursor-dev libxi-dev libxinerama-de…

矩阵碰一碰发视频之 API 接口接入技术开发全解析,支持OEM

矩阵碰一碰发视频作为一种创新的视频分享方式&#xff0c;为用户带来了便捷且独特的体验。而在这一功能的实现过程中&#xff0c;API 接口接入扮演着至关重要的角色。通过接入合适的 API&#xff0c;能够高效地实现视频数据的传输、设备间的通信以及用户交互等功能。本文将深入…

第二十二天 学习HarmonyOS的分布式软总线技术,了解跨设备通信的原理

前言 在万物互联时代&#xff0c;跨设备协同成为智能生态系统的核心需求。HarmonyOS通过创新的分布式软总线技术&#xff0c;实现了设备间的高效通信与资源共享。本文将从零开始&#xff0c;带领开发者深入理解这项核心技术&#xff0c;通过代码实战演示如何构建跨设备应用。我…

网络渗透作业

第一题&#xff1a;使用Xpath对Order by 语句进行布尔盲注 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml&quo…

AI DEV 人工智能能做的工作,在开发运维安全方面以及企业成本降低方面所起的作用和相应的提示词。

这个查询是用中文提出的&#xff0c;询问人工智能在开发、运维、安全方面以及企业成本降低方面的作用和相应的提示词。我应该用中文回答&#xff0c;并涵盖以下几个方面&#xff1a; AI在软件开发中的应用AI在IT运维中的应用AI在网络安全中的应用AI如何帮助企业降低成本针对这…