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

2024-02-27 10:28

本文主要是介绍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);}}
}

总结

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

这篇关于WPF 【十月的寒流】学习笔记(2):MVVM中是怎么实现通知的的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/752093

相关文章

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被