当前位置: 首页 > news >正文

WPF 【十月的寒流】学习笔记(2):MVVM中是怎么实现通知的

文章目录

  • 前言
  • 相关链接
  • 代码仓库
  • 项目配置
  • 代码
    • 初始代码
      • View
      • Person
      • ViewModel
    • 尝试老办法通知
    • 解决方案
      • ObservableCollection
      • BindingList
      • ICollectionView
  • 总结

前言

我们这次详细了解一下列表通知的底层是怎么实现的

相关链接

十月的寒流

在这里插入图片描述
在这里插入图片描述

MVVM实战技巧之:可被观测的集合(ObservableCollection & BindingList)

代码仓库

我为了方便展示源代码,我将代码提交到了代码仓库里面

B站【十月的寒流】对应课程的代码 Github仓库

项目配置

如何使用我这里就不展开说明了

WPF CommunityToolkit.Mvvm

WPF CommunityToolkit.Mvvm Messenger通讯

在这里插入图片描述

WPF-UI HandyControl 简单介绍

WPF-UI HandyControl 控件简单实战+IconPacks矢量图导入

在这里插入图片描述

Bogus,.NET生成批量模拟数据
在这里插入图片描述

代码

初始代码

View

 <UserControl.DataContext><viewModels:DemoViewModel /></UserControl.DataContext><DockPanel><StackPanel DockPanel.Dock="Bottom"><Button Command="{Binding AddItemCommand}"Content="添加数据"></Button></StackPanel><DataGrid ItemsSource="{Binding People}"></DataGrid></DockPanel>

Person

public class Person
{public int Id { get; set; }public string FirstName { get; set; }public string LastName { get; set; }public string FullName { get; set; }public DateOnly BirthDay { get; set; }public static Person FakerOne => faker.Generate();public static IEnumerable<Person> FakerMany(int count)=>faker.Generate(count);private static readonly Faker<Person> faker = new Faker<Person>().RuleFor(t=>t.Id,f=>f.IndexFaker).RuleFor(t=>t.FirstName,f=>f.Name.FirstName()).RuleFor(t=>t.LastName,f=>f.Name.LastName()).RuleFor(t=>t.FullName,f=>f.Name.FullName()).RuleFor(t=>t.BirthDay,f=>f.Date.BetweenDateOnly(new DateOnly(1990,1,1),new DateOnly(2010,1,1)));
}

ViewModel

public partial class DemoViewModel:ObservableObject
{[ObservableProperty]private List<Models.Person> people = new List<Models.Person>();[RelayCommand]public void AddItem(){People.Add(Models.Person.FakerOne);}public DemoViewModel() {People = Models.Person.FakerMany(5).ToList();}}

现在的代码是没有实现通知,点击按钮也不会添加

在这里插入图片描述

尝试老办法通知

        public void AddItem(){People.Add(Models.Person.FakerOne);//没有效果//OnPropertyChanged(nameof(People));//没有效果//SetProperty(ref people, people);}

而且在我们点击ListBox的时候,会报错。这个就说明,其实List已经修改了,但是这个通知方法不行。原因是List指向的是一个地址空间,这个地址空间并没有变化。
在这里插入图片描述

解决方案

ObservableCollection

简单的解决方案就是改成ObservableCollection,这里就不展开说明了。
在这里插入图片描述
但是有一个问题,这个ObservableCollection只在Count更新的时候触发自动更新。里面的Person值修改的时候是不会触发更新的。

如果有联动更新的需求,可以直接在【CollectionChanged】添加对应的代码
在这里插入图片描述

BindingList

这里我就不展开说明了,直接上视频的源代码了。

在这里插入图片描述
在这里插入图片描述

ICollectionView

WPF 【十月的寒流】学习笔记(1):DataGrid过滤

更好的解决方案就是直接更新。我们直接刷新ItemSorce

<UserControl x:Class="WpfMvvmDemo.Views.DemoView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfMvvmDemo.Views"xmlns:viewModels="clr-namespace:WpfMvvmDemo.ViewModels"mc:Ignorable="d"d:DesignHeight="450"d:DesignWidth="800"><UserControl.DataContext><viewModels:DemoViewModel /></UserControl.DataContext><DockPanel><StackPanel DockPanel.Dock="Bottom"HorizontalAlignment="Left"Orientation="Horizontal"><Button Command="{Binding AddItemCommand}"Margin="5"Content="添加数据"></Button><Button Command="{Binding UpIdCommand}"Margin="5"Content="增加Id"></Button></StackPanel><DataGrid ItemsSource="{Binding PeopleView}"></DataGrid></DockPanel>
</UserControl>
using Bogus;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;namespace WpfMvvmDemo.ViewModels
{public partial class DemoViewModel:ObservableObject{[ObservableProperty]private List<Models.Person> people = new List<Models.Person>();[ObservableProperty]private ICollectionView peopleView;[RelayCommand]public void AddItem(){People.Add(Models.Person.FakerOne);//没有效果//OnPropertyChanged(nameof(People));//没有效果//SetProperty(ref people, people);//直接更新整个视图源PeopleView.Refresh();}[RelayCommand]public void UpId(){foreach (var item in People){item.Id += 10;}PeopleView.Refresh();}public DemoViewModel() {People = Models.Person.FakerMany(5).ToList();PeopleView = CollectionViewSource.GetDefaultView(People);}}
}

为了方便,我们也可以直接新建一个类,这里就把代码放一下,就不展开说明了

    public class CollectionData<T> where T : class{public IEnumerable<T> Data { get; set; }public ICollectionView CollectionView { get; set; }public CollectionData() { }public void Init(){CollectionView = CollectionViewSource.GetDefaultView(Data);CollectionView.Refresh();}}

总结

我觉得当时【十月的寒流】那个视频一直在想用MVVM去通知更新,当然他的主题也是使用MVVM自动更新。但是ItemSorce随时都有可能发生修改。要么就是每次事件之后修改,要么就给每个可能会触发的属性添加通知。

相关文章:

WPF 【十月的寒流】学习笔记(2):MVVM中是怎么实现通知的

文章目录 前言相关链接代码仓库项目配置代码初始代码ViewPersonViewModel 尝试老办法通知解决方案ObservableCollectionBindingListICollectionView 总结 前言 我们这次详细了解一下列表通知的底层是怎么实现的 相关链接 十月的寒流 MVVM实战技巧之&#xff1a;可被观测的集合…...

数据结构:广义表

定义&#xff1a;有序数列  表示&#xff27;&#xff2c;&#xff1d;&#xff08;&#xff41;&#xff08;&#xff42;&#xff0c;&#xff43;&#xff09;&#xff09;长度 &#xff12;&#xff0c; 表头&#xff1a;&#xff41; 表尾&#xff1a;&#xff08;&am…...

你好,C++(18) 到底要不要买这个西瓜?4.1.6 操作符之间的优先顺序

你好&#xff0c;C&#xff08;18&#xff09; 到底要不要买这个西瓜&#xff1f;4.1.6 操作符之间的优先顺序 4.1.6 操作符之间的优先顺序 在表达一些比较复杂的条件判断时&#xff0c;在同一个表达式中&#xff0c;有时可能会存在多个操作符。比如&#xff0c;我们在判断要…...

C语言 for 循环语句的基本格式是什么?

一、问题 for 循环语句在C语⾔中是最为常见的循环语句&#xff0c;其功能强⼤&#xff0c;⽽且⽤法灵活&#xff0c;那么它的基本格式是什么呢&#xff1f; 二、解答 for 语句的⼀般形式为&#xff1a; for(表达式1;表达式2;表达3&#xff09;语句; 每条 for 语句包含三个⽤分…...

项目-SERVER模块-日志宏

日志宏 #define INF 0 #define DBG 1 #define ERR 2#define LOG_LEVEL INF #define LOG(level, format, ...) do {\if (level < LOG_LEVEL) break;\time_t t time(NULL);\struct tm *ltm localtime(&t);\char tmp[32] {0};\strftime(tmp, 31, "%H:%M:%S"…...

TCP为什么要三次握手?

TCP三次握手协议是为了在不可靠的互联网环境中可靠地建立起一个连接&#xff0c;三次握手可以确保两端的发送和接收能力都是正常的。 那么&#xff0c;为什么是三次而不是二次或四次握手呢&#xff1f; 为什么不是二次握手&#xff1f; 如果是二次握手&#xff0c;即客户端发…...

网络防御第6次作业

防病毒网关 按照传播方式分类 病毒 病毒是一种基于硬件和操作系统的程序&#xff0c;具有感染和破坏能力&#xff0c;这与病毒程序的结构有关。病毒攻击的宿主程序是病毒的栖身地&#xff0c;它是病毒传播的目的地&#xff0c;又是下一次感染的出发点。计算机病毒感染的一般过…...

Jmeter分布式部署

前期准备&#xff1a; 1. 控制机一台&#xff0c;代理机一台&#xff0c;Jmeter安装包 操作步骤&#xff1a; 1. Linux安装Jmeter&#xff08;windows安装教程自己搜一下&#xff09; 1.1创建一个单独的文件夹(jmeter)&#xff0c;用来存放Jmeter的安装包 mkdir jmeter 1.2…...

Odoo迈入开源第一低代码开发平台的重要里程碑

Odoo17的正式发布已经过去好几个月了&#xff0c;通过一段时间的运用&#xff0c;最大的感触就是&#xff0c;Odoo会成为企业管理软件低代码开发平台的重要一员&#xff0c;而V17则会成为这个过程中具有里程碑意义的版本。 时隔四个月&#xff0c;让我们回头来看看Odoo17带来的…...

WinForm、Wpf自动升级 AutoUpdater.NET

Github AutoUpdater.NET 目录 一、IIS部署 更新站点 二、创建Winform 一、IIS部署 更新站点 IIS默认站点目录下创建 目录 Downloads、Updates Updates目录创建文件 UpdateLog.html、AutoUpdaterStarter.xml UpdateLog.html&#xff1a; <html><body><h1…...

GPU不够用:语言模型的分布式挑战

引言 随着深度学习技术的飞速发展,大规模语言模型(LLM)在各种NLP任务中取得了令人瞩目的成绩。然而,这些模型的大小和复杂度也不断增加,给部署和应用带来了诸多挑战。特别是在单个GPU或服务器的内存容量有限的情况下,如何高效地利用分布式计算资源成为了一个亟待解决的问…...

深入理解Redis中的渐进式Rehash技术

1. 引言 Redis是一款高性能的键值存储系统,被广泛应用于缓存、队列、计数器等场景,因其快速、稳定的特性备受开发者青睐。在Redis的背后,有着许多复杂的数据结构和算法支撑着其高效运行,而其中之一就是Rehash操作。 Rehash是Redis中的一个关键操作,负责在数据量增加时对…...

数据结构 栈和队列 力扣例题AC——代码以及思路记录

20. 有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应…...

管理类联考--复试--英文面试--各校英文面试内容

文章目录 北京地区北京大学中国人民大学北京交通大学北京航空航天大学北方工业大学北京林业大学北京语言大学中央财经大学对外经济贸易大学首都经济贸易大学华北电力大学中国矿业大学中国石油大学北京国家会计学院中国财政科学院研究院北京理工大学北京工商大学中国农业大学 湖…...

Android修行手册-Chaquopy中opencv、numpy的初步应用

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…...

VBA将当前打开的表格生成PDF图片

前言 VBA将当前的表格存储成PDF文件进行存储 代码 Sub ExportToPDF()Dim FilePath As StringDim FileName As StringDim ExportRange As Range 设置导出文件路径及名称FilePath "D:\Users\"FileName "ExportedPDF" 设置导出区域范围Set ExportRange Ra…...

解锁AI大模型秘籍:未来科技的前沿探索

在当今这个技术高速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了我们生活中不可或缺的一部分。从简单的个人助手到复杂的数据分析和决策制定&#xff0c;AI的应用范围日益扩大&#xff0c;其目的是为了让我们的生活变得更加智能化。本文旨在探讨AI如何…...

一文带你了解MySQL之B+树索引的原理

前言 学完前面我们讲解了InnoDB数据页的7个组成部分&#xff0c;知道了各个数据页可以组成一个双向链表&#xff0c;而每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表&#xff0c;每个数据页都会为存储在它里边儿的记录生成一个页目录&#xff0c;在通过主键查…...

【Vue】npm run build 打包报错:请在[.env.local]中填入key后方可使用...

报错如下 根目录添加 .env.local 文件 .env.local &#xff1a;本地运行下的配置文件 配置&#xff1a;VUE_GITHUB_USER_NAME 及 VUE_APP_SECRET_KEY 原因...

中国电子学会2020年06月真题C语言软件编程等级考试三级(含详细解析答案)

中国电子学会考评中心历届真题&#xff08;含解析答案&#xff09; C语言软件编程等级考试三级 2020年06月 编程题五道 总分:100分一、最接近的分数&#xff08;20分&#xff09; 分母不超过N且小于A/B的最大最简分数是多少? 时间限制: 1000ms 内存限制: 65536kb 输入…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

tomcat指定使用的jdk版本

说明 有时候需要对tomcat配置指定的jdk版本号&#xff0c;此时&#xff0c;我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...