关于ObservableCollection的更新与不更新分析

yizhihongxing

因为最近在WPF项目中,遇到ObservableCollection这个属性的频繁使用,一个一个坑跳过来,今天看到这个贴子

玩转INotifyPropertyChanged和ObservableCollection - 包建强 - 博客园 (cnblogs.com)

其中分析很透彻了,但是留了一点遗憾,而且在其中引起了一个想法,做一个项目来测试一下。

我们知道在Binding一个item的时候,想要其中属性变化时,UI同步变化,需要实现OnPropertyChanged接口,我因为习惯于mvvm.Toolkit,也就是说需要继承ObservableObject,

类似这样:

 public class Student:ObservableObject
    {
        private string name;
        public string Name
        {
            get => name;
            set => SetProperty(ref name, value);
        }
        private int age;
        public int Age
        {
            get => age;
            set=>SetProperty(ref age, value);
        }
}

在Binding到集合项的时候,通常需要这样

pulic  ObservableCollection<Student> Students_t = new ();

通过上面2条,可以实现:集合中增加、删除元素,及元素属性更新的时候,UI可自动更新。

但是,但是的但是,如果需要刷新数据的时候,比如说,人工清除当前集合,重新从源头读取,通常这样:

Students=new ObservableCollection<Student>(ctx.students)

这就坏了,发现UI没更新。原因在于,ObservableCollection只关注内部的元素变化,但当他自己发生了变化,其实对集合Binding关系已经破坏了,因为这是一个新建的集合,等于更新了Students这个对象,而不是对这个对象的内部元素作出的增删。

希望我说得明白了。

如果我说明白了,就是说,前面我们忽略了一个问题。

Students仍然不是可观察对象。

所以,要修改为

 private ObservableCollection<Student> students_c = new ();
public ObservableCollection<Student> Student_c
        {
            get => students_c;
            set => SetProperty(ref students_c, value);
        }
}

开始我说的忽发奇想是,如果我对List<T>实现可观察,是否能够代替了ObservableCollection?测试结果是,是的,在重置数据的时候,确实是可以实现的(很奇怪吗?),但是在增删元素的时候,仍然不行,仍然需要ObservableCollection。

对以上各种情况,我做的测试项目,见:

https://gitee.com/ppcba/observable-collection-demo.git

如果有同样疑惑的,建议参考着自己做一下,不然会仍然糊涂着。

==========2023-5-7补充=========

ObservableCollection的重置还有一种场景,就是自身不带AddRange方法,只好更新它后面的数据源,习惯上是这样使用的:

StuList.AddRange(stus);
Students=New ObservableCollection<Student>(StuList);

这就使得ObservableCollection被重置了。

所以,我现在项目上,仍然把ObservableCollection作为字段,而不是属性,需要重置的时候,就清空,然后使用扩展方法AddRange方法。

但从MVVM强迫症的角度,还是一切OnPropertyChanged进行到底为好。

原文链接:https://www.cnblogs.com/cbaa/archive/2023/05/06/17378609.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于ObservableCollection的更新与不更新分析 - Python技术站

(0)
上一篇 2023年5月7日
下一篇 2023年5月7日

相关文章

  • C#中Entity Framework常见报错汇总

    下面是详细讲解“C#中EntityFramework常见报错汇总”的完整攻略。 C#中EntityFramework常见报错汇总 1. 连接字符串错误 连接字符串错误是EntityFramework中最常见的错误之一。连接字符串属于配置信息中的一部分,提供给DbContext使用。连接字符串可以包含数据库的名称、数据库服务器的名称(或IP)和其他必要的信息,…

    C# 2023年5月15日
    00
  • Winform跨线程操作的简单方法

    下面我将详细讲解Winform跨线程操作的简单方法。相信本文对正在开发Winform程序的小伙伴们一定会有所帮助。 前言 Winform 是非常强大的桌面应用程序开发工具,但是在某些情况下,我们需要在不同的线程之间进行控件操作,例如在 UI 线程以外的线程中更新 UI 控件,这就需要进行跨线程操作。 解决方法 方法一:使用 Invoke 使用 Invoke …

    C# 2023年6月7日
    00
  • 深入C# 内存管理以及优化的方法详解

    深入C# 内存管理以及优化的方法详解 在C#中,内存管理是一个非常重要的话题。由于C#运行于托管环境中,所以我们通常不需要手动管理内存。但是,仍然有一些情况需要我们了解和优化内存管理。本文将为你详细探讨C#内存管理和优化的方法,同时会提供一些示例。 内存管理 通常情况下,C#的垃圾回收器(GC)会自动管理内存。GC会自动回收无用的对象,并且为我们管理内存。但…

    C# 2023年6月7日
    00
  • WCF实现进程间管道通信Demo分享

    下面是关于“WCF实现进程间管道通信Demo分享”的完整攻略,包含两个示例。 1. 什么是进程间管道通信 进程间管道通信是一种在不同进程之间进行通信的方法。在Windows操作系统中,可以使用命名管道(Named Pipe)来实现进程间管道通信。命名管道是一种命名的、双向的、异步的、字节流管道,可以在本地或远程计算机之间进行通信。 2. WCF实现进程间管道…

    C# 2023年5月15日
    00
  • 一个读写csv文件的C#类

    下面是一个读写CSV文件的C#类的完整攻略。 需求分析 我们需要一个能够读取和写入CSV文件的C#类,使得我们能够方便地在程序中进行CSV文件的读写操作。 设计思路 我们的CSV文件读写类需要实现以下功能:1. 读取CSV文件2. 写入CSV文件3. 支持设置CSV文件的分隔符 我们可以使用C#中的StreamReader和StreamWriter类来实现C…

    C# 2023年6月1日
    00
  • C#实现单链表(线性表)完整实例

    为了更好的阐述“C#实现单链表(线性表)完整实例”这一主题,在下面的回答中我们将会涉及以下两个方面: 单链表的原理以及相关概念; C#语言实现单链表的完整攻略。 单链表的原理及概念 单链表是常用的一种链式存储结构,因为其结构形式极其简单,便于操作和改变长度,所以经常用作链表的头结点。简单的来说,单链表由若干个结点组成,每个结点包括一个存放元素的数据域(可以为…

    C# 2023年6月1日
    00
  • C# BinaryReader.Close – 关闭二进制读取器

    C#中的BinaryReader类是一个自.NET Framework 1.1版本引入的类,用于从二进制流中读取基本数据类型。该类有一个Close方法,本文将详细讲解该方法的作用和使用方法。 关于BinaryReader.Close方法的作用 BinaryReader.Close方法用于关闭BinaryReader对象读取的流。当对象读取完成后,应该尽快关闭…

    C# 2023年4月19日
    00
  • C#加密app.config中连接字符串的方法

    以下是详细讲解“C#加密app.config中连接字符串的方法”的完整攻略: 1. 什么是app.config连接字符串 在使用C#开发应用程序时,可能需要将连接数据库时使用的信息存储在app.config文件中。该文件通常被称为应用程序配置文件,其中包含有关应用程序设置的信息,包括数据库连接字符串、应用程序窗口大小、应用程序特定的设定等。 连接字符串也是应…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部