WPF中MVVM的应用举例

news2024/11/29 19:41:06

WPF(Windows Presentation Foundation)是微软开发的用于创建用户界面的框架,而MVVM(Model-View-ViewModel)模式是一种分离前端UI逻辑与后台业务逻辑的方法。在WPF中使用MVVM模式可以提高代码的可维护性、可测试性和可扩展性。在这篇文章中,我们将深入探讨WPF中的MVVM模式,并通过具体的代码示例来展示其应用。

在这里插入图片描述

一、MVVM 模式概述

在这里插入图片描述

1.1 模型(Model)

Model 是应用程序的业务逻辑层,负责数据的处理、验证和操作。它通常与数据库或网络服务交互,并且应该是独立于 View 和 ViewModel 的。因此,Model 层不应该包含与 UI 相关的代码。

1.2 视图(View)

View 是用户界面层,负责数据的显示和用户交互。它通常是由 XAML 文件定义的。View 通过数据绑定(Data Binding)与 ViewModel 进行交互,而不是直接与 Model 交互。View 中不应该包含业务逻辑,而是通过绑定与 ViewModel 进行数据和命令的交互。

1.3 视图模型(ViewModel)

ViewModel 是 MVVM 的核心,充当 View 和 Model 之间的桥梁。它通常包含 View 的状态、操作和命令。ViewModel 实现了 INotifyPropertyChanged 接口,以支持数据绑定的通知机制,这样当 ViewModel 的属性发生变化时,View 可以自动更新。

二、WPF 中 MVVM 模式的优势

在这里插入图片描述

  • 分离关注点:通过将 UI 和业务逻辑分离,开发者可以专注于各自的职责,这使得代码更易于理解和维护。
  • 可测试性:业务逻辑被移到了 ViewModel 中,并且不依赖于具体的 UI,使得逻辑单元更容易进行自动化测试。
  • 可维护性和可扩展性:通过使用绑定和命令,UI 变化不需要改变业务逻辑代码,从而提高了代码的可维护性和可扩展性。

三、WPF 中 MVVM 模式的应用示例

接下来,我们将通过一个具体的示例来展示如何在 WPF 中实现 MVVM 模式。我们将创建一个简单的应用程序,允许用户在文本框中输入姓名,然后在另一个文本框中显示问候语。

3.1 创建项目

首先,打开 Visual Studio,并创建一个新的 WPF 应用程序项目。

3.2 创建 Model 类

Model 类可以是简单的数据类,只包含姓名属性。以下是一个示例:

public class UserModel
{
    public string Name { get; set; }
}
3.3 创建 ViewModel 类

ViewModel 类用于管理数据和业务逻辑。我们将在其中实现 INotifyPropertyChanged 接口,以便当属性变化时通知 View 进行更新。

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class UserViewModel : INotifyPropertyChanged
{
    private UserModel _userModel;
    private string _greeting;

    public UserViewModel()
    {
        _userModel = new UserModel();
    }

    public string Name
    {
        get => _userModel.Name;
        set
        {
            _userModel.Name = value;
            OnPropertyChanged();
            UpdateGreeting();
        }
    }

    public string Greeting
    {
        get => _greeting;
        private set
        {
            _greeting = value;
            OnPropertyChanged();
        }
    }

    private void UpdateGreeting()
    {
        Greeting = $"Hello, {_userModel.Name}!";
    }
    
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

在这段代码中,UserViewModel 通过 INotifyPropertyChanged 通知 View 数据的变化。Name 属性的更改会自动更新 Greeting 属性。

3.4 创建 View

View 是 XAML 文件,负责定义用户界面。在 MainWindow.xaml 中,添加以下代码:

<Window x:Class="MVVMDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MVVM Demo" Height="200" Width="400">
    <Grid>
        <StackPanel Margin="10">
            <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" 
                     Width="200" Height="30" Margin="0,0,0,10"/>
            <TextBlock Text="{Binding Greeting}" Width="200" Height="30"/>
        </StackPanel>
    </Grid>
</Window>

在 XAML 中,我们通过 DataContext 进行数据绑定。TextBoxText 属性绑定到 ViewModel 的 Name 属性,TextBlockText 绑定到 Greeting 属性。

3.5 将 ViewModel 绑定到 View

在 MainWindow.xaml.cs 中,将 ViewModel 绑定到 View 的 DataContext。

public partial class MainWindow : Window
{
    private UserViewModel _viewModel;

    public MainWindow()
    {
        InitializeComponent();
        _viewModel = new UserViewModel();
        this.DataContext = _viewModel;
    }
}

四、扩展 MVVM 应用

在这里插入图片描述

以上是一个简单的 MVVM 实例。为了更好地理解 MVVM 模式,我们可以进一步扩展这个示例,包括命令的使用、数据验证以及与其他服务(如数据库或网络服务)交互。

4.1 使用命令

命令是 MVVM 中用于替代事件处理的一种方式。通过使用命令,我们可以将用户交互(如按钮点击)与业务逻辑分离。MVVM 提供了 ICommand 接口用于实现命令。

以下是一个简单的命令实现:

using System;
using System.Windows.Input;

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add => CommandManager.RequerySuggested += value;
        remove => CommandManager.RequerySuggested -= value;
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

然后,我们可以在 UserViewModel 中创建命令:

public ICommand ShowGreetingCommand { get; }

public UserViewModel()
{
    _userModel = new UserModel();
    ShowGreetingCommand = new RelayCommand(
        p => UpdateGreeting(),
        p => !string.IsNullOrWhiteSpace(Name)
    );
}

在 XAML 中绑定命令:

<Button Content="Show Greeting" Command="{Binding ShowGreetingCommand}" Width="100" Height="30" />

使用命令后,Show Greeting 按钮只有在 Name 属性不为空时才可用。

五、总结

MVVM 模式在 WPF 应用程序中的应用,可以极大地提高代码的组织性和可维护性。通过分离 UI、业务逻辑和数据模型,我们创建了一个清晰、可测试和可扩展的架构。在实际项目中,使用 MVVM 模式可以帮助开发者更高效地合作,使应用程序更易于维护和扩展。

在实施过程中,理解数据绑定、命令模式和通知机制是使用 MVVM 模式的关键。熟练掌握这些技术将帮助开发者在现代软件开发中更高效地使用 WPF 和其他基于 XAML 的技术。

print("拥抱新技术才是王道!")

关注我,不迷路,共学习,同进步

关注我,不迷路,共学习,同进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2215694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vant 日期时间组件拓展

基于 "vant": "^4.8.3", 效果图 <template><!-- 弹出层 --><van-popupv-model:show"isPicker"position"bottom"><van-pickerref"picker":title"title"v-model"selectedValues"…

匿名管道和命名管道

目录 管道 pipe创建一个管道 让子进程写入&#xff0c;父进程读取 如何把消息发送/写入给父进程 父进程该怎么读取呢 管道本质 结论&#xff1a;管道的特征&#xff1a; 测试管道大小 写端退了&#xff0c;测试结果 测试子进程一直写&#xff0c;父进程读一会就退出 …

PAT甲级-1076 Forwards on Weibo

题目 题目大意 已知微博上粉丝都可能会转发自己所关注的人的动态&#xff0c;给定总人数n和层数l&#xff0c;和每个id关注的人数及所关注人的id。要求查询一组用户的潜在转发量&#xff0c;粉丝层级不能超过l。 思路 求潜在转发量&#xff0c;就是一层一层的找粉丝数&#…

【已知当前表字段名注入】

一、通配符注入 like 测试注入 usernameadmin&passwordadmin 提示username or password error输入单引号闭合测试 这里用or防止admin字段不存在数据库中&#xff0c;如果admin不存在用and连接admin不为真&#xff0c;username的逻辑还是没绕过&#xff0c;用or就算我们前面…

嵌入式Linux开发板配置静态IP

嵌入式Linux开发板配置静态IP Chapter1 嵌入式Linux开发板配置静态IPChapter2 Linux命令之hwclock - 查询和设置硬件时钟 Chapter1 嵌入式Linux开发板配置静态IP 修改interfaces配置文件&#xff0c;普通用户interfaces文件权限只可读&#xff0c;首先切换到root权限。 sudo …

vue单页面 与多页面的区别

引用&#xff08;【Vue相关】单页面应用(SPA)与多页面应用(MPA)的区别_vue mpa-CSDN博客&#xff09; 只要用框架基本上都是单页面工程

特斯拉全新发布会上,无人驾驶汽车亮相,机器人与用户近距离互动

在科技日新月异的今天&#xff0c;特斯拉再次以其前瞻性的技术和创新理念引领了行业的潮流。近日&#xff0c;特斯拉在美国加利福尼亚州伯班克华纳兄弟工作室召开了一场主题为“WE ROBOT”的新品发布会&#xff0c;会上不仅发布了无人驾驶汽车&#xff0c;还展示了特斯拉人形机…

4S店汽车行业专业线上小程序源码系统 功能强大 带完整的安装代码包以及搭建部署教程

系统概述 随着移动互联网的迅速发展&#xff0c;越来越多的传统行业开始拥抱数字化转型。在汽车销售领域&#xff0c;4S店&#xff08;即集整车销售、零配件供应、售后服务、信息反馈四位于一体的汽车服务企业&#xff09;也不例外。为了更好地服务于客户&#xff0c;并提升自…

C++11——异常

异常的介绍 异常是C1中的一种处理错误的方式&#xff0c;当某一函数发现自己无法处理的错误时就可以抛出异常&#xff0c;让函数的直接或间接的调用者处理这个错误&#xff0c;异常的使用可以避免一些难以发现的bug被更好的发现并被处理。 异常的使用 异常的使用包含是三个部…

从空口分析BLE AUDIO ASCS

ASCS&#xff1a;AUDIO STREAM CONTROL SERVICE&#xff0c;音频流控制服务&#xff0c;顾名思义会对音频流的一些参数去做控制的服务&#xff0c;下面我们还是以手机和耳机为例&#xff0c;结合空口来分析ASCS都有哪些内容&#xff1a; 1&#xff1a;ASE CODEC CONFIG 配置A…

保姆级教程下载finalshell以及连接云服务器基础的使用教程

废话不多说&#xff0c;我们直接进行安装 一、软件下载 下载地址&#xff1a; FinalShell SSH工具,服务器管理,远程桌面加速软件,支持Windows,macOS,Linux,版本4.5.10,更新日期2024.9.26 - FinalShell官网 (hostbuf.com)https://www.hostbuf.com/t/988.html 点击链接进行下载…

【Next.js 项目实战系列】01-创建项目

原文链接 CSDN 的排版/样式可能有问题&#xff0c;去我的博客查看原文系列吧&#xff0c;觉得有用的话&#xff0c;给我的库点个star&#xff0c;关注一下吧 创建项目 创建项目​ 在创建项目中可以找到相关内容&#xff0c;这里不再赘述 First commit​ 创建好项目之后&am…

40个IT运维加薪技术,每一个都含金量极高!运维必会的10个网络抓包/调试工具!系统崩溃的10种可能,运维人员必看!

40个IT运维加薪技术&#xff0c;每一个都含金量极高!运维必会的10个网络抓包/调试工具&#xff01;系统崩溃的10种可能&#xff0c;运维人员必看&#xff01; 在IT运维领域&#xff0c;想要加薪并不仅仅依赖于单一的技术&#xff0c;而是需要综合运用多种技能&#xff0c;不断提…

【LangChain】(一)掌握向量数据库的CRUD操作与语义检索技巧

文章目录 1. 向量数据库的基础知识1.1 为什么选择向量数据库&#xff1f; 2. CRUD操作详解2.1 向量数据库-新增数据示例代码&#xff1a; 2.2 向量数据库-删除数据示例代码&#xff1a; 2.3 向量数据库-更新数据2.4 向量数据库-查询数据2.4.1 相似度查询2.4.2 最大边际相关性查…

React(二) JSX中的this绑定问题;事件对象参数传递;条件渲染;列表渲染;JSX本质;购物车案例

文章目录 一、jsx事件绑定1. 回顾this的绑定方式2. jsx中的this绑定问题(1) 方式一&#xff1a;bind绑定(2) 方式二&#xff1a;使用 ES6 class fields 语法(3) 方式三&#xff1a;直接传入一个箭头函数(重要) 3.事件参数传递(1) 传递事件对象event(2) 传递其他参数 4. 事件绑定…

DeepBook V3和DEEP token正式上线

10月14日&#xff0c;DeepBook V3版本正式在主网上线&#xff0c;同时发布了DEEP token&#xff0c;标志着其发展历程中的一个重要里程碑。通过这次升级&#xff0c;用户和做市商将受益于精细调控的激励措施&#xff0c;为通过社区驱动的治理实现更大的去中心化奠定了基础。 D…

【大模型问答测试】大模型问答测试脚本实现(第一版)

背景 公司已经做了一段时间的大模型&#xff0c;每次测试或者回归的时候都需要针对问答进行测试回归&#xff0c;耗费大量的时间与精力&#xff0c;因此结合产品特点&#xff0c;开发自动化脚本替代人工的操作&#xff0c;提升测试回归效率 设计 使用pythonrequestExcel进行…

python+大数据+基于Spark的共享单车数据存储系统【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

【jQuery】 jQuery基础及选择器介绍(基本选择器 层次选择器 属性选择器 过滤选择器)

文章目录 jQuery基础1. 优势2. 版本3. 基本语法4. 选择器基本选择器层次选择器属性选择器过滤选择器基本过滤选择器可见性过滤选择器 注意事项 jQuery基础 jQuery 是一个功能强大且易于使用的 JavaScript 库&#xff0c;它极大地简化了前端开发的工作。无论是 DOM 操作、事件处…

简单概述Ton链开发路径

区块链开发领域发展迅速&#xff0c;各种平台为开发人员提供不同的生态系统。其中一个更有趣且越来越相关的区块链是TON&#xff08;开放网络&#xff09;区块链。TON 区块链最初由 Telegram 构思&#xff0c;旨在提供快速、安全且可扩展的去中心化应用程序 (dApp)。凭借其独特…