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

因为最近在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/p/17378609.html

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

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

相关文章

  • Unity中 mesh生成斜坡的示例代码

    下面我为你详细讲解如何在Unity中生成斜坡的示例代码。 Unity中mesh生成斜坡的示例代码 1. 创建空白的GameObject 首先我们需要在场景中创建一个空白的GameObject。你可以在Unity的菜单栏中选择GameObject -> CreateEmpty来创建它。 2. 添加MeshFilter和MeshRenderer组件 选中G…

    C# 2023年5月15日
    00
  • C#实现23种常见的设计模式的示例详解

    使用Markdown编写“C#实现23种常见的设计模式的示例详解”的完整攻略可以如下: C#实现23种常见的设计模式的示例详解 什么是设计模式 设计模式指的是,在特定情况下,针对某种问题所提供的可行解决方案。也就是说,设计模式是对问题的一种解决方案,而不是代码的一种实现。它们是经过验证、被证明是有效的解决方案,并且在不同的场景下可以复用的。 设计模式的分类 …

    C# 2023年6月6日
    00
  • 使用Log4net进行日志记录

    使用Log4net进行日志记录是一项非常重要的任务,因为它可以帮助开发者更好地了解应用程序的运行状态,检测并解决在调试和测试期间遇到的问题。下面就是关于如何使用Log4net进行日志记录的完整攻略: 步骤一:安装Log4net 首先,你需要在你的应用程序中下载并安装Log4net。你可以在NuGet管理器中搜索“log4net”,然后安装最新版本。 步骤二:…

    C# 2023年5月15日
    00
  • C#开发的人脸左右相似度计算软件源码分析

    介绍C#开发的人脸左右相似度计算软件 “C#开发的人脸左右相似度计算软件”是一种基于C#语言编写的人脸图像处理工具,可以对输入的人脸图像进行左右对称处理,并计算出左右两侧差异的相似度值。该软件集成OpenCV人脸识别库和C#图形用户界面,可以方便地进行人脸相似度计算和可视化展示。 解析源码 该软件主要包括以下几个模块: 图像加载与处理:使用OpenCV库加载…

    C# 2023年6月7日
    00
  • C#字符串内存驻留机制分析

    C#字符串内存驻留机制分析 什么是字符串内存驻留机制 C#中使用字符串常量池进行内存共享,其中长度相同且内容相同的字符串只会在内存中存在一份拷贝。当程序中声明了一个字符串常量时,如果该字符串内容已经存在于池中,那么常量会直接指向内存池中的共享内存区域。这个机制就是字符串内存驻留机制。其可以减少内存使用,提高程序运行效率。 字符串内存驻留机制的实现方式 小字符…

    C# 2023年5月31日
    00
  • ASP.NET设计网络硬盘之两重要类代码

    我可以为您提供关于“ASP.NET设计网络硬盘之两重要类代码”的完整攻略。 概述 在ASP.NET网络硬盘设计中,有两个重要的类可以帮助我们实现文件的上传、下载和管理功能。这两个类是FileUpload和Directory。 FileUpload类 FileUpload类是ASP.NET框架中的一个控件,用于上传文件到Web服务器。使用该控件可以轻松方便地实…

    C# 2023年5月31日
    00
  • asp.net直接Response输出WML页面示例代码

    当我们需要在 ASP.NET 程序中输出 WML 页面时,可以使用 Response.Write 方法直接将 WML 页面代码输出到响应流中。以下是实现该功能的完整攻略: 第一步:设置响应内容类型 在 ASP.NET 程序中,我们需要设置响应内容类型,以便浏览器能够正确解析页面。对于 WML 页面,我们需要设置响应内容类型为 “text/vnd.wap.wm…

    C# 2023年5月31日
    00
  • 使用VSCode开发和调试.NET Core程序的方法

    使用VSCode开发和调试.NET Core程序的方法 在本攻略中,我们将详细介绍如何使用VSCode开发和调试.NET Core程序。我们将提供两个示例说明,演示如何使用VSCode创建和调试.NET Core Web应用程序和控制台应用程序。 前置条件 在开始之前,需要确保已经安装了以下软件: .NET Core SDK Visual Studio Co…

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