MVVM_MVVMLight架构

news2024/9/21 18:44:02

介绍

MVVMLight是一个实现MVVM模式的轻量级框架(相对于Prism),能够更好的帮助我们开发WPF Windows Phone、Windows 8、SilverLight相关项目。

安装

在NuGet 工具箱上搜索MVVMLight进行下载

下载后它帮你生成ViewModel文件夹,里面包含MainViewModel和ViewModelLocator文件,然后需要自己建立一个完整的架构目录。

当安装完成之后由于版本原因在ViewModelLocator文件中的using引用会报错进而导致程序无法执行,所以需要修改引用。

将报错的using Microsoft.Practices.ServiceLocation; 引用修改为using CommonServiceLocator;

分层架构

1、View负责前端展示,与ViewModel进行数据和命令的交互。

2、ViewModel,负责前端视图业务级别的逻辑结构组织,并将其反馈给前端。

3、Model,主要负责数据实体的结构处理,与ViewModel进行交互。

MVVMLight架构的使用

1.在Model写一个实体对象用于和ViewModel交互

在MVVMLight中使用ObservableObject类实现实时监听数据变更。

ObservableObject,这个父类的作用就是保证能够检测属性是否被改变。它实现了INotifyPropertyChanged接口,通过触发PropertyChanged事件达到通知UI更改的目的,所以我们在定义实体对象的时候,只需要调用RaisePropertyChanged(PropertyName)就可以进行属性更改通知了。

public class WelcomeModel : ObservableObject
        {
            private String introduction;
            public String Introduction
            {
                get { return introduction; }
                set { introduction = value; RaisePropertyChanged(()=>Introduction); }
            }
        }

2.写一个ViewModel用于和View交互

此类继承了ViewModelBase父类,ViewModelBase同时继承 ObservableObject类和ICleanup接口。所以他同样有INotifyPropertyChanged接口的能力,能够通过触发PropertyChanged事件达到通知View的目的;构造函数中对 Welcome 属性进行了实例化。

public class WelcomeViewModel:ViewModelBase
        {
            /// <summary>
            /// 构造函数
            /// </summary>
            public WelcomeViewModel()
            {
                Welcome = new WelcomeModel() { Introduction = "Hello World!" };
            }
            #region 属性
    
            private WelcomeModel welcome;
            /// <summary>
            /// 欢迎词属性
            /// </summary>
            public WelcomeModel Welcome
            {
                get { return welcome; }
                set { welcome = value; RaisePropertyChanged(()=>Welcome); }
    
                M1 = new RelayCommand(f1);// 给指令赋值
            }
            
            public RelayCommand M1 { get;set; }
            // 回调函数 无返回值
            public void f1()
            {
                MessageBox.Show("f1");
            }
            #endregion
        }

3.写一个View,来显示数据和交互ViewModel。

TextBlock 绑定了 Welcome.Introduction,所以应该显示Welcome对象下的Introduction属性。   

<Window x:Class="MVVMLightDemo.View.WelcomeView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WelcomeView" Height="300" Width="300">
        <Grid>
            <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" >
                <TextBlock Text="{Binding Welcome.Introduction}" FontSize="30" ></TextBlock>
                <Button Width="200" Command="{Binding M1}" Height="40">点击</Button>
            </StackPanel>
        </Grid>
    </Window>

把 WelcomeViewModel 赋值给当前视图的数据上下文。所以可以在当前视图中使用ViewModel中所有的公开属性和命令。

    using MVVMLightDemo.ViewModel;
    using System.Windows;
    
    namespace MVVMLightDemo.View
    {
        /// <summary>
        /// Interaction logic for WelcomeView.xaml
        /// </summary>
        public partial class WelcomeView : Window
        {
            public WelcomeView()
            {
                InitializeComponent();
                this.DataContext = new WelcomeViewModel();
            }
        }
    }

构造器

所以每次App初始化的时候,就会去初始化ViewModelLocator类。

实际上他就是一个很基本的视图模型注入器。在构造器中把使用到的ViewModel统一注册,并生成单一实例。然后使用属性把它暴露出来,每当我们访问属性的时候,就会返回相应的ViewModel实例。

第一步在APP.xaml中添加引用

<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />

    <Application x:Class="MVVMLightDemo.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 StartupUri="View/WelcomeView.xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 d1p1:Ignorable="d"
                 xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:vm="clr-namespace:MVVMLightDemo.ViewModel" >
      <Application.Resources>
        <ResourceDictionary>
                <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
        </ResourceDictionary>
      </Application.Resources>
    </Application>

第二步在ViewModelLocator类中注册对象并且实例化

下文中实例化的MainViewModel就是用于和View交互ViewModel中的类

namespace MVVMLightDemo.ViewModel
    {
        public class ViewModelLocator
        {
            /// <summary>
            /// Initializes a new instance of the ViewModelLocator class.
            /// </summary>
            public ViewModelLocator()
            {
                ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
                // 1.先注册对应的vm对象
                SimpleIoc.Default.Register<MainViewModel>();
            }
            // 2.实例化
            #region 实例化
            public MainViewModel Main
            {
                get
                {
                    return ServiceLocator.Current.GetInstance<MainViewModel>();
                }
            }
    
            #endregion
    
            public static void Cleanup()
            {
                // TODO Clear the ViewModels
            }
        }
    }

第三步在xaml中绑定

DataContext="{Binding Source= {StaticResource Locator},Path=Main}"

我们可以将后台CS中的 this.DataContext = new WelcomeViewModel(); 可以去掉了,直接在WelcomeView中这样写:

DataContext="{Binding Source={StaticResource Locator},Path=Welcome}",

这种写法当我们绑定到数据,编译之后就会立马呈现

服务端开发人员可以专心写ViewModel的业务逻辑代码,UI开发人员可以专注设计视图了,同样 ViewModel可以绑定到不同的视图上,所以从这边就可以体现出他其中的三个重要特性:低耦合、可重用性、独立开发。 ViewModelLocator 类中还有个 ClearnUp()方法,主要目的用来清除ViewModel实例的。ViewModelBase继承了GalaSoft.MvvmLight.ICleanup接口,并在自己的类中写好了Cleanup()虚方法。所以我们在实例ViewModel类中可以重写Cleanup()来达到清除当前实例的目的。

伟大的双向绑定

场景: 当数据发生变化时 数据源跟着发生变化 进而触发数据更新,另一条绑定数据源的数据也会跟着发生变化

下文中UpdateSourceTrigger属性的作用是 当做何种改变的时候通知数据源我们做了改变。

     <StackPanel Orientation="Vertical" Margin="10,10,0,0">
                <StackPanel Margin="0,10,0,0" Orientation="Horizontal" >
                    <TextBlock Text="Hello " ></TextBlock>
                    <TextBlock Text="{Binding UserInfo.UserName}" ></TextBlock>
                </StackPanel>
    
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal" >
                </StackPanel>
    
            </StackPanel>

(当修改输入框的内容的时候,对应绑定数据相应改变,并触发对UI的修改,所以下面那行文字也相应改变改变。)

UpdateSourceTrigger属性:

枚举类型效果  
Default默认值(默认为LostFocuse)
Explicit当应用程序调用 UpdateSource 方法时生效
LostFocus失去焦点的时候触发
PropertyChanged数据属性改变的时候触发

这边我们直接使用 PropertyChanged,当UI数据改变的时候,我们再通知到数据源去做修改。

还有一个属性就是Mode,他有五个参数:

枚举类型效果
OneWay源发生变化,数据就会从源流向目标
OneTime绑定会将数据从源发送到目标;但是,仅当启动了应用程序或 DataContext 发生更改时才会如此操作,因此,它不会侦听源中的更改通知。
OneWayToSource绑定会将数据从目标发送到源
TwoWay绑定会将源数据发送到目标,但如果目标属性的值发生变化,则会将它们发回给源
Default绑定的模式根据实际情况来定,如果是可编辑的就是TwoWay,只读的就是OneWay

这边明显有很多种选择,明确一点的是,我们是想把View上的变化同步到ViewModel(Target => Source),所以使用OneWayToSource、TwoWay、Default或者不写都可以。严谨点应该使用OneWayToSource。因为是文本框,属于可以编辑控件,所以 Default指向的是TwoWay。下面还有一个TextBlock,仅仅用于显示的,所以不需要目标对源的修改,无需指定就默认是OneWay,当源改变的时候,会通知它进行修改。

MVVMLight架构详细介绍学习网站

https://www.cnblogs.com/wzh2010/category/937606.html

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

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

相关文章

深度学习之基于Tensorflow卷积神经网络脑肿瘤分类识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 脑肿瘤是医学领域的一个重要问题&#xff0c;对人类的健康构成了严重威胁。传统的脑肿瘤分类识别方法…

老的 IIS + MSSQL 网站迁移实例

因为公司需要从云上迁移回本地&#xff0c;但云平台不愿意导出虚拟机文件&#xff0c;所以公司需要手工迁移。 查看了一下云主机&#xff0c;安装了IIS&#xff0c;还有MSSQL数据库&#xff0c;于是在本地搭建好相同的OSIISMSSQL 环境&#xff0c;在把数据库导入完成、 IIS 搭建…

AcWing 217:绿豆蛙的归宿 ← 搜索算法

【题目来源】https://www.acwing.com/problem/content/219/【题目描述】 给出一个有向无环的连通图&#xff0c;起点为 1&#xff0c;终点为 N&#xff0c;每条边都有一个长度。 数据保证从起点出发能够到达图中所有的点&#xff0c;图中所有的点也都能够到达终点。 绿豆蛙从起…

iptables防火墙【☆】

一、防火墙的基础 防火墙分为硬件防火墙和软件防火墙&#xff0c;硬件防火墙有专门的设备&#xff1a;如国产华为、绿盟等&#xff0c;作为网关层做地址转换等安全防护。很多公司基本都会使用硬件防火墙做第一道防御&#xff0c;在核心业务上再添加软件防火墙提高安全性能…

Tailwind CSS快速入门

文章目录 初识安装Tailwindcss试用安装快速书写技巧扩展好处Todo 初识 只需书写 HTML 代码&#xff0c;无需书写 CSS&#xff0c;即可快速构建美观的网站 Tailwind CSS 是一个功能类优先的 CSS 框架&#xff0c;它通过提供大量的原子类&#xff08;utility classes&#xff09;…

国产操作系统上使用SQLynx连接数据库 _ 统信 _ 麒麟 _ 中科方德

原文链接&#xff1a;国产操作系统上使用SQLynx连接数据库 | 统信 | 麒麟 | 中科方德 Hello&#xff0c;大家好啊&#xff01;今天我们将探讨如何在国产操作系统上使用SQLynx。这是一款功能强大的数据库管理工具&#xff0c;可以帮助用户高效地管理和操作数据库。本文将详细介绍…

《网关微服务技术架构:构建高效可扩展的服务网关》

随着微服务架构的流行&#xff0c;网关微服务作为微服务架构中的重要组成部分&#xff0c;扮演着连接客户端与后端微服务的关键角色。本文将深入探讨网关微服务的技术架构设计与实现&#xff0c;以及如何构建高效可扩展的服务网关。 ### 1. 网关微服务的作用与意义 网关微服务…

【Power Compiler手册】2.Power Compiler设计流程

当创建设计时,它从高层次的抽象转移到门级最终实现。功耗编译器工具在整个设计周期中,从RTL到门级,提供分析和优化。 有关设计流程的信息,请参见以下主题: • 设计周期中的功耗 • 功耗优化和分析流程 设计周期中的功耗 在每个抽象层次上,使用仿真、分析和优化来完善…

GMSL图像采集卡,适用于无人车、自动驾驶、自主机器、数据采集等场景,支持定制

基于各种 系列二代 G MS L 图像采集卡&#xff08;以下简称 二代图像采集卡&#xff09;是一款自主研发的一款基于 F P G A 的高速图像产品&#xff0c;二代图像采集卡相比一代卡&#xff0c;由于采用PCIe G en 3 技术&#xff0c;速度和带宽都相应的有了成 倍的提高。该图像…

递归的例子

例1&#xff1a;阶乘函数 #include<iostream> using namespace std; int f(int n) {if(n0)return 1;elsereturn f(n-1)*n; } int main() {int n;cin>>n;cout<<f(n);return 0; }例2&#xff1a;Fibonacci数列 无穷数列1&#xff0c;1&#xff0c;2&#xff0…

微服务:eureka的搭建,以及服务注册、服务发现、负载均衡

eureka 搭建 新建一个Module,maven项目&#xff0c;导入依赖。 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><…

Day 59 503.下一个更大元素Ⅱ 42.接雨水

下一个更大元素Ⅱ 给定一个循环数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&#xff09;&#xff0c;输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&#xff0c;这意味着你应该循环…

JVM学习-动态链接和方法返回地址

动态链接–指向运行时常量池的方法引用 每一个栈帧内部包含一个指向运行时常量池中该栈帧所属方法的引用&#xff0c;包含这个引用的目的为了支持当前方法的代码能够实现动态链接(Dynamic Linking)&#xff0c;如invokednamic指令。在Java源文件被编译到字节码文件中时&#x…

【字典树(前缀树) 位运算】1803. 统计异或值在范围内的数对有多少

本文涉及知识点 字典树&#xff08;前缀树&#xff09; 位运算 LeetCode1803. 统计异或值在范围内的数对有多少 给你一个整数数组 nums &#xff08;下标 从 0 开始 计数&#xff09;以及两个整数&#xff1a;low 和 high &#xff0c;请返回 漂亮数对 的数目。 漂亮数对 是…

运维出现的问题 --集成

运维出现的问题 集成 macos 本地打的镜像&#xff0c;推到线上出现 images platform (linux/arm64) does not match the detected解决办法 macos 本地打的镜像&#xff0c;推到线上出现 image’s platform (linux/arm64) does not match the detected WARNING: The requested …

抖音视频怎么去水印保存部分源码|短视频爬虫提取收集下载工具

抖音视频怎么去水印保存部分源码|短视频爬虫提取收集下载工具 抖音视频去水印保存部分源码&#xff1a; 通过使用Python中的requests、re和os等库&#xff0c;可以编写如下代码来实现抖音视频去水印保存的功能。 短视频爬虫提取手机下载工具的使用方法&#xff1a; 该工具主…

项目集成SkyWalking,基于k8s搭建

一、搭建SkyWalking 官方文档&#xff08;英文&#xff09;&#xff1a;skywalking/docs at master apache/skywalking 中文可以使用&#xff1a;GitHub - SkyAPM/document-cn-translation-of-skywalking: [已过期,请使用官网AI文档] The CN translation version of Apache…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-19讲 串口实验UART

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

跟着Kimi学习结构化提示词:19套内置提示词都在这里了!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

Android Studio 版本升级后 Gradle project sync failed(Android V 应用升级)

问题及解决方案 更新到蜥蜴 Android Studio Iguana 后&#xff0c;出现Gradle project sync failed的问题&#xff08;IDE更新版本的常态了&#xff09;。 背景&#xff1a;对应用进行Android V版本升级&#xff08;SDK35&#xff0c;gradle插件版本要 8.4.0&#xff09; 1、…