C# WPF上位机开发(MVVM模式开发)

news2025/1/21 1:05:43

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        学习过vue的同学都知道mvvm这个名词。从字面上理解,可能有点拗口,但是我们可以去理解一下它的优点是什么。mvc相信大家都明白,m就是model,v就是view,c就是control。model的话,一般就是数据,目前大多数就是数据库里面的data;v就是view,可以是网页,可以是前端;c的话,就是control,简单的看就是控件的各个回调函数。

        当然,这是mvc。现在又出了一个mvvm。本质上,mvvm相当于提供了一种双向绑定的模式。即界面中的显示和实际的数据bind在一起。这样数据发生任何的改变,用户不需要重新渲染界面了。这对开发的同学来说,是十分方便的。为了说明双向绑定是怎么使用的,我们可以写一个简单的demo说明一下。

1、设计MainWindow.xaml文件

<Window x:Class="WpfApp.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"
        xmlns:local="clr-namespace:WpfApp"
        Title="MVVMDemo" Height="300" Width="300">

    <Window.DataContext>
        <local:PersonViewModel/>
    </Window.DataContext>

    <Grid>
        <StackPanel Margin="10">
            <TextBlock Text="First Name:"/>
            <TextBox   Text="{Binding FirstName, Mode=TwoWay}" Margin="0,0,0,10"/>
            <TextBlock Text="Last Name:"/>
            <TextBox   Text="{Binding LastName, Mode=TwoWay}" Margin="0,0,0,10"/>

            <!-- New Labels to Display FirstName and LastName -->
            <TextBlock Text="First Name Displayed:"/>
            <Label Content="{Binding FirstName}" Margin="0,0,0,10"/>
            <TextBlock Text="Last Name Displayed:"/>
            <Label Content="{Binding LastName}" Margin="0,0,0,10"/>
            <Button Content="Button" Click="Button_Click"/>
        </StackPanel>
    </Grid>
</Window>

        整个界面和之前相比较,最大的不同就是多了一个DataContext。里面有一个类,就是后面要实现的PersonViewModel。另外,在Grid里面,我们看到有四个Binding,其实是两组。每一组都有一个FirstName,一个LastName。除此之外呢,还有一个Button,它主要是演示怎么从外面给界面发数据。而里面的输入呢,相当于从界面发给数据。

        出来的效果应该是这样的,

2、设计MainWindow.xaml.cs文件

        主窗口中有一个按钮,需要设计一个回调函数。它的主要目的就是利用DataContext给FirstName和LastName传值。按钮按下去之后呢,不管是txt中的内容,还是label中的内容,都会发生改变。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var model = this.DataContext as PersonViewModel;
            model.FirstName = "Tom";
            model.LastName = "Cruise";
        }
    }
}

3、设计PersonViewModel.cs

        整个代码中,最重要的部分就是INotifyPropertyChanged的实现。xaml中我们看到了PersonViewModel这个类,到时候系统会创建一个实例。数据发生改变的时候,就会调用对应的set函数。在set函数中,我们会进一步调用子函数OnPropertyChanged,通知所有关注这个property的函数。假设没有这个函数,前面窗口中txt中数据更新之后,label中的数据是不会更新的。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApp
{
    public class PersonViewModel : INotifyPropertyChanged
    {
        public static PersonModel _person;

        public PersonViewModel()
        {
            _person = new PersonModel();
        }

        public string FirstName
        {
            get { return _person.FirstName; }
            set
            {
                if (_person.FirstName != value)
                {
                    _person.FirstName = value;
                    OnPropertyChanged(nameof(FirstName)); // invoke here
                }
            }
        }

        public string LastName
        {
            get { return _person.LastName; }
            set
            {
                if (_person.LastName != value)
                {
                    _person.LastName = value;
                    OnPropertyChanged(nameof(LastName)); // invoke here
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        // invoke after value was set
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class PersonModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

}

        总结一下,前面我们说过双向绑定,它的意思就界面的修改和传递给变量,那么变量的修改也可以传递给界面。MainWindows中实现的是变量传给界面,而PersonViewModel实现的相当于界面传给变量。

4、编译和测试

        编译没有问题的话,就可以开始测试了。测试的时候,我们可以在txt中输入不同的数据,下面的label也会做同步的显示。这一步测试之后,我们就可以单机一下按钮,看txt中的内容有没有同步改变。如果两者都没有问题,那么就代表mvvm测试ok了。

        一开始测试的情景,

        这个时候,如果我们设置一下Button,就会变成这样,

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

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

相关文章

InDesign插件-常规功能开发-添加参考线-js脚本开发-ID插件

文章目录 1.脚本执行概述2.InDesign 对象模型3.源码解析4.界面及结果5.总结 1.脚本执行概述 “脚本”面板和“脚本标签”面板概述&#xff0c;InDesign 包含两个用于脚本的面板&#xff1a;“脚本”面板和“脚本标签”面板。在“脚本”面板中可以运行脚本而不必离开 InDesign。…

Python sanic框架钉钉和第三方打卡机实现

同样还是需要开通钉钉应用这里就不错多说了 第一步:梳理逻辑流程 前提&#xff1a;打卡的机器是使用postgres数据库&#xff0c;由于因为某些原因&#xff0c;钉钉userId 我已经提前获取到了存放到数据库里。 1.用户打卡成功后&#xff0c;我们应该监听数据库进行查询&#xf…

【教学类-35-07】17号的字帖(三)年份字帖“2023”(A4竖版1份)

作品展示 前四行是一个数字的描写 后四行是合并的年份4个数字 背景需求&#xff1a; 大4班17号孩子练习数字书写&#xff0c;上一次是“17”号和大“4”&#xff0c;第3份就是年份 【教学类-35-05】17号的学号字帖&#xff08;A4竖版1份&#xff09;-CSDN博客文章浏览阅读4…

数据结构--查找

目录 1. 查找的基本概念 2. 线性表的查找 3. 树表的查找 3.1 二叉排序树 3.1.1 定义: 3.1.2 存储结构&#xff1a; 3.1.3 二叉排序树的查找 3.1.4 二叉排序树的插入 3.1.5 二叉排序树删除 3.2 平衡二叉树&#xff08;AVL 3.2.1 为什么要有平衡二叉树 3.2.2 定义 3.3 B-树 3.3.1…

Flink1.17实战教程(第五篇:状态管理)

系列文章目录 Flink1.17实战教程&#xff08;第一篇&#xff1a;概念、部署、架构&#xff09; Flink1.17实战教程&#xff08;第二篇&#xff1a;DataStream API&#xff09; Flink1.17实战教程&#xff08;第三篇&#xff1a;时间和窗口&#xff09; Flink1.17实战教程&…

Flink项目实战篇 基于Flink的城市交通监控平台(上)

系列文章目录 Flink项目实战篇 基于Flink的城市交通监控平台&#xff08;上&#xff09; Flink项目实战篇 基于Flink的城市交通监控平台&#xff08;下&#xff09; 文章目录 系列文章目录1. 项目整体介绍1.1 项目架构1.2 项目数据流1.3 项目主要模块 2. 项目数据字典2.1 卡口…

信息网络协议基础-IPv6协议

文章目录 概述为什么引入IP服务模型IPv4的可扩展性问题解决方法***CIDR(Classless Inter-Domain Routing, 无类别域间寻路)前缀汇聚***前缀最长匹配***NAT(网络地址转换)存在的问题解决方案路由表配置***局限性IPv6协议头标IPv6地址表示前缀类型单播地址链路局部地址(Link-Loca…

RabbitMq知识概述

本文来说下RabbitMq相关的知识与概念 文章目录 概述AMQP协议Exchange 消息如何保证100&#xff05;投递什么是生产端的可靠性投递可靠性投递保障方案 消息幂等性高并发的情况下如何避免消息重复消费confirm 确认消息、Return返回消息如何实现confirm确认消息return消息机制 消费…

构建高效数据中台:集群规划与搭建的最佳实践指南

架构设计 Rack(机架)配置建议 大数据集群规划 安装细节见配套文档 两地三中心 两地三中心是一种信息技术架构模式,通常用于灾难恢复和业务连续性计划。这种模式设计有两个物理位置(两地),在这两个位置上部署了三个数据中心(三中心):一个主数据中心和两个备份数据中心…

电子邮件过滤软件SpamSieve mac高级功能

SpamSieve mac是一款电子邮件过滤软件&#xff0c;旨在帮助用户有效地识别和阻止垃圾邮件。该软件可通过机器学习算法自动学习您的邮箱中哪些邮件是垃圾邮件&#xff0c;哪些是正常邮件&#xff0c;并根据您的反馈不断优化过滤效果。 使用SpamSieve非常简单&#xff0c;只需将其…

How to Develop Word Embeddings in Python with Gensim

https://machinelearningmastery.com/develop-word-embeddings-python-gensim/ 本教程分为 6 个部分;他们是&#xff1a; 词嵌入 Gensim 库 开发 Word2Vec 嵌入 可视化单词嵌入 加载 Google 的 Word2Vec 嵌入 加载斯坦福大学的 GloVe 嵌入 词嵌入 单词嵌入是一种提供单词的…

HTML的学习记录

<br /> 标签在 HTML 页面中创换行符。 <hr /> 标签在 HTML 页面中创建水平线。 段落是通过 <p> 标签定义的。 浏览器会自动地在段落的前后添加空行。&#xff08;<p> 是块级元素&#xff09; 文本格式 <b>This text is bold</b>字体加粗 …

腾讯云轻量应用服务器购买流程(两种方式)

腾讯云轻量应用服务器购买指南&#xff0c;有两个入口&#xff0c;一个是在特价活动上购买&#xff0c;一个是在轻量应用服务器官方页面购买&#xff0c;特价活动上购买价格更便宜&#xff0c;轻量2核2G3M带宽服务器62元一年起&#xff0c;阿腾云atengyun.com分享腾讯云轻量应用…

VS配置PCO相机SDK环境

VS配置PCO相机SDK环境 概述:最近要用到一款PCO相机,需要协调其他部件实现一些独特的功能。因此需要用到PCO相机的SDK,并正确配置环境。良好的环境是成功的一半。其SDK可以在官网下载,选择对应版本的安装即可。这里用的是pco.cpp.1.2.0 Windows,VS 2022 专业版。 链接: P…

阿里云 ACK 云上大规模 Kubernetes 集群高可靠性保障实战

作者&#xff1a;贤维 马建波 古九 五花 刘佳旭 引言 2023 年 7 月&#xff0c;阿里云容器服务 ACK 成为首批通过中国信通院“云服务稳定运行能力-容器集群稳定性”评估的产品&#xff0c; 并荣获“先进级”认证。随着 ACK 在生产环境中的采用率越来越高&#xff0c;稳定性保…

【python 的各种模块】(8) 在python使用matplotlib和wordcloud库来画wordcloud词云图

目录 目标&#xff1a;用python画出&#xff0c;网上流行的wordcloud词云图 1 准备工作 1.1环境准备 1.1.1安装步骤 1.2 资源准备 1.2.1 文本文件内容如下 1.2.2 图片资源 2 代码测试 2.1 第一版代码和效果 2.1.1 代码和效果 2.1.2 一般plt里解决中文乱码问题 2.1…

StackOverflowError的JVM处理方式

背景&#xff1a; 事情来源于生产的一个异常日志 Caused by: java.lang.StackOverflowError: null at java.util.stream.Collectors.lambda$groupingBy$45(Collectors.java:908) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.ArrayL…

基于飞浆OCR的文本框box及坐标中心点检测JSON格式保存文本

OCR的文本框box及JSON数据保存 需求说明 一、借助飞浆框出OCR识别的文本框 二、以圆圈形式标出每个框的中心点位置 三、以JSON及文本格式保存OCR识别的文本 四、以文本格式保存必要的文本信息 解决方法 一、文本的坐标来自飞浆的COR识别 二、借助paddleocr的draw_ocr画出…

【数据库系统概论】第4章-数据库安全性

复习用&#xff0c;别看了 文章目录 4.1 计算机安全性概述4.2 数据库安全性控制4.2.1 用户标识和鉴定4.2.2 存取控制4.2.3 自主存取控制方法4.2.4 数据库角色4.2.5 强制存取控制 4.3 视图机制4.4 审计4.5 数据加密4.6 其他安全性保护 4.1 计算机安全性概述 不安全因素 4.2 …

项目管理计划(word版21页)

本计划的主要目的是通过本方案明确本项目的项目管理体系。方案的主要内容包括&#xff1a;明确项目的目标及工作范围&#xff0c;明确项目的组织结构和人员分工&#xff0c;确立项目的沟通环境&#xff0c;确立项目进度管理方法&#xff0c;明确项目跟踪和监控方式&#xff0c;…