关于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日

相关文章

  • asp.net错误捕获(错误处理)page_error事件使用方法

    当ASP.NET应用程序运行时,可能会发生许多错误,如页面不存在、数据库连接丢失、未处理异常等。这些错误可能会使您的应用程序崩溃或给用户带来糟糕的体验。为此ASP.NET提供了一个Page_Error事件来捕获未处理的错误并进行处理。 下面是使用Page_Error事件的示例: void Page_Error(object sender, EventArgs…

    C# 2023年5月15日
    00
  • 在WPF中合并两个ObservableCollection集合

    在WPF中合并两个ObservableCollection集合的攻略可以分为以下步骤: 1. 创建两个ObservableCollection集合 首先,我们需要创建两个不同的ObservableCollection集合,并分别往其中添加数据,如下所示: ObservableCollection<string> collection1 = new…

    C# 2023年6月6日
    00
  • matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析

    Matplotlib是一个具有强大绘图功能的Python库,其运行时配置(Runtime Configuration,rc)参数rcParams可以设置绘图参数,如字体大小、线条宽度、颜色等,使得Matplotlib绘图更加个性化、符合需求。 rcParams是一个Python字典对象,包含了Matplotlib的所有绘图参数设置。可以通过修改字典中的键值对…

    C# 2023年5月31日
    00
  • C#多线程的ResetAbort()方法

    下面是关于C#多线程中ResetAbort()方法的详细讲解: ResetAbort()方法简介 ResetAbort()是多线程中的一个方法,它用于取消挂起的线程并重置线程的中止状态。当我们使用Abort()方法中止一个线程时,如果无法中止该线程,则该线程将被挂起,并且它的中止状态将被设置为一个标志,表示该线程已经被中止。此时,我们可以使用ResetAbo…

    C# 2023年5月15日
    00
  • C# TabControl控件中TabPage选项卡切换时的触发事件问题

    C#的TabControl控件中,TabPage选项卡的切换可以由用户手动点击或者程序动态切换两种方式触发,对应的事件就是TabControl的SelectedIndexChanged事件。下面将详细讲解如何在C#中处理TabControl控件中TabPage选项卡切换的问题。 监听TabControl的SelectedIndexChanged事件 当用户手…

    C# 2023年5月15日
    00
  • .NET Core系列之MemoryCache 初识

    .NET Core系列之MemoryCache 初识 在本攻略中,我们将详细讲解.NET Core中的MemoryCache,包括其基本概念、使用方法和示例说明。 MemoryCache简介 MemoryCache是.NET Core中的一个内存缓存库,可以用于缓存应用程序中的数据。它提供了一种快速、可靠和高效的方式来缓存数据,以提高应用程序的性能和响应速度…

    C# 2023年5月16日
    00
  • C#实现打字小游戏

    下面是讲解C#实现打字小游戏的完整攻略。 一、介绍 打字小游戏,是一种很有趣的游戏,可以提高我们的打字速度和准确率。在这个项目中,我们将使用C#语言来实现一个简单的打字小游戏。 二、准备工作 在开始编写代码之前,我们需要先准备好以下工具和环境: C#集成开发环境,如Visual Studio; .NET Framework; Windows操作系统。 三、思…

    C# 2023年6月7日
    00
  • C# TextWriter.WriteLine – 写入一行字符

    下面是关于C#的TextWriter.WriteLine方法的详细讲解: 1. 方法介绍 TextWriter.WriteLine方法是一个 .NET 中的基础类库,用于将指定的文本行写入一个或多个文本流中,并在行之后添加一个换行符。该方法定义在System.IO命名空间中。 public virtual void WriteLine(string? val…

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