本文仅作为参考大佬们文章的总结。

ObservableCollection是C#中一个功能强大的动态数据集合类,特别适用于需要数据绑定和UI自动更新的场景。本文将系统性地总结ObservableCollection的核心概念、使用方法、性能优化策略以及在实际项目中的应用实践。

一、ObservableCollection基础概念

1. 定义与特性

ObservableCollection<T>是System.Collections.ObjectModel命名空间下的一个泛型集合类,它继承自Collection<T>并实现了INotifyCollectionChanged和INotifyPropertyChanged接口。其核心特性包括:

  • ​自动变更通知​​:当集合中的元素被添加、移除或整个列表被重置时,会自动触发CollectionChanged事件

  • ​UI同步更新​​:特别适用于WPF、UWP等需要数据绑定的框架,能够确保UI元素实时反映数据变化

  • ​动态数据管理​​:提供标准的集合操作方法如Add、Remove、Insert等

2. 与普通List的区别

ObservableCollection与普通List的主要区别在于变更通知机制:

特性

ObservableCollection

List

变更通知

支持(INotifyCollectionChanged)

不支持

UI自动更新

适用场景

数据绑定/UI更新

后台数据处理

内存占用

略高(需维护事件机制)

更低

线程安全性

需通过Dispatcher调用

需手动同步

3. 核心应用场景

ObservableCollection特别适用于以下场景:

  1. ​WPF/UWP数据绑定​​:与ListBox、DataGrid等控件绑定,实现数据-UI自动同步

  2. ​实时监控系统​​:如聊天应用消息列表、股票行情显示等需要实时更新的界面

  3. ​MVVM架构​​:作为ViewModel中的集合属性,连接Model和View

  4. ​配置管理系统​​:需要动态反映配置变化的场景

二、基本使用方法

1. 初始化与基本操作

使用ObservableCollection首先需要引用System.Collections.ObjectModel命名空间:

using System.Collections.ObjectModel;// 初始化
var collection = new ObservableCollection<string>();// 添加元素
collection.Add("Item1");
collection.Add("Item2");// 移除元素
collection.Remove("Item1");// 插入元素
collection.Insert(0, "NewItem");

2. 数据绑定示例

在WPF中,ObservableCollection可以轻松实现数据绑定:

<!-- XAML中定义ListBox绑定 -->
<ListBox ItemsSource="{Binding Items}" DisplayMemberPath="Name"/>
// ViewModel中定义集合属性
public class MainViewModel
{public ObservableCollection<Item> Items { get; } = new ObservableCollection<Item>();public MainViewModel(){// 初始化数据Items.Add(new Item { Name = "Item1" });Items.Add(new Item { Name = "Item2" });}
}

当通过Add、Remove等方法修改集合时,UI会自动更新,无需手动刷新。

3. 监听集合变更

可以通过CollectionChanged事件监听集合变化:

collection.CollectionChanged += (sender, e) =>
{Console.WriteLine($"变更类型: {e.Action}");if (e.NewItems != null){Console.WriteLine($"新增项数: {e.NewItems.Count}");}if (e.OldItems != null){Console.WriteLine($"移除项数: {e.OldItems.Count}");}
};

事件参数NotifyCollectionChangedEventArgs包含以下重要属性:

  • ​Action​​:变更类型(Add、Remove、Replace、Move、Reset)

  • ​NewItems​​:新增项的集合

  • ​OldItems​​:移除项的集合

  • ​NewStartingIndex​​:新增项的起始索引

  • ​OldStartingIndex​​:移除项的起始索引

三、高级应用技巧

1. 批量操作优化

标准ObservableCollection在进行批量操作时会对每个操作单独触发事件,可能导致性能问题。解决方案是使用ObservableRangeCollection:

// 使用MvvmCross中的ObservableRangeCollection
var rangeCollection = new ObservableRangeCollection<int>();
var itemsToAdd = Enumerable.Range(1, 1000).ToArray();// 批量添加,只触发一次事件
rangeCollection.AddRange(itemsToAdd);

ObservableRangeCollection提供了以下批量操作方法:

  • AddRange:批量添加

  • RemoveRange:批量移除

  • ReplaceRange:批量替换

2. 与INotifyPropertyChanged结合

当集合中的元素属性变化时,也需要通知UI更新。这需要元素类实现INotifyPropertyChanged接口:

public class Person : INotifyPropertyChanged
{private string _name;public string Name{get => _name;set{_name = value;OnPropertyChanged(nameof(Name));}}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}

这样,当Person对象的Name属性变化时,绑定的UI也会相应更新。

3. 跨线程访问处理

ObservableCollection不是线程安全的,在非UI线程修改集合会导致异常。解决方案是通过Dispatcher或SynchronizationContext:

// WPF中使用Dispatcher
Application.Current.Dispatcher.Invoke(() =>
{collection.Add(newItem);
});// 使用SynchronizationContext
SynchronizationContext uiContext = SynchronizationContext.Current;
uiContext.Post(_ => 
{collection.Remove(oldItem);
}, null);

4. 集合视图与筛选排序

可以通过CollectionViewSource对ObservableCollection进行筛选和排序:

var cvs = new CollectionViewSource { Source = collection };
cvs.View.Filter = item => ((Person)item).Age > 18; // 筛选成年人
cvs.View.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));// 绑定到View
listBox.ItemsSource = cvs.View;

四、性能优化

1. 性能考量

虽然ObservableCollection提供了便利的变更通知,但在某些场景下需要注意性能问题:

  1. ​批量操作​​:频繁的单元素操作会导致多次事件触发,应尽量使用批量方法

  2. ​大型集合​​:对于包含数千项的大型集合,应考虑分页或虚拟化技术

  3. ​复杂UI​​:复杂控件(如DataGrid)绑定大型集合时可能性能下降

2. 使用建议

根据实际场景选择合适的集合类型:

  • ​需要UI自动更新​​:使用ObservableCollection

  • ​纯数据处理/高频操作​​:使用List

  • ​需要批量操作​​:使用ObservableRangeCollection或自定义扩展方法

3. 扩展方法示例

可以为ObservableCollection添加自定义扩展方法提高便利性:

public static class ObservableCollectionExtensions
{public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items){foreach (var item in items){collection.Add(item);}}public static void ReplaceAll<T>(this ObservableCollection<T> collection, IEnumerable<T> items){collection.Clear();foreach (var item in items){collection.Add(item);}}
}

五、应用案例

1. 学生管理系统

使用ObservableCollection实现学生信息的增删改查:

public class StudentManager
{public ObservableCollection<Student> Students { get; } = new ObservableCollection<Student>();// 添加学生public void AddStudent(Student student){Students.Add(student);}// 删除学生public void RemoveStudent(int studentId){var student = Students.FirstOrDefault(s => s.Id == studentId);if (student != null){Students.Remove(student);}}// 更新学生信息public void UpdateStudent(Student updatedStudent){var index = Students.IndexOf(Students.First(s => s.Id == updatedStudent.Id));if (index >= 0){Students[index] = updatedStudent;}}
}

2. 实时数据监控

构建实时监控系统,显示不断更新的数据:

public class DataMonitorViewModel
{public ObservableCollection<DataPoint> DataPoints { get; }= new ObservableCollection<DataPoint>();private Timer _updateTimer;public DataMonitorViewModel(){// 定时更新数据_updateTimer = new Timer(UpdateData, null, 0, 1000);}private void UpdateData(object state){var newData = GetLatestDataFromService();// 确保在UI线程更新Application.Current.Dispatcher.Invoke(() =>{DataPoints.Clear();foreach (var data in newData){DataPoints.Add(data);}});}
}

六、常见问题与解决方案

  1. ​UI不更新问题​

    • 确保绑定的属性是public且可读

    • 检查是否实现了INotifyPropertyChanged

    • 确认数据上下文(DataContext)设置正确

  2. ​线程访问冲突​

    • 确保在UI线程修改集合

    • 使用Dispatcher或SynchronizationContext跨线程调用

  3. ​性能问题​

    • 对于大型集合,考虑使用虚拟化面板(VirtualizingPanel)

    • 避免频繁的单元素操作,改用批量方法

  4. ​内存泄漏​

    • 及时取消事件订阅

    • 避免长期持有集合引用

参考:

  1. 【三】ObservableCollection 与 List 的区别
  2. list和ObservableCollection的区别
  3. C#将每个无线局域网配置文件存储在ObservableCollection中
  4. C# WPF入门学习主线篇(二十八)—— 使用集合(ObservableCollection)
  5. C#中的ObservableCollection及其数据绑定中的作用
  6. C#中的 ObservableCollection 、ObservableRangeCollection
  7. 动态数据集合ObservableCollection的使用
  8. C#集合类ObservableCollection与List的区别和使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/91514.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/91514.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/91514.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

佰力博检测与您探讨超高温介电测试的应用领域

超高温介电测试是指在极端高温条件下&#xff08;通常高于1000℃&#xff09;对材料的介电性能进行测量和分析的过程。以评估材料在高温环境下的电学性能稳定性&#xff0c;如介电常数、介电损耗、阻抗谱等参数。超高温介电测试需要用到的超高温介电阻抗测试设备&#xff1a;UT…

OneCode自治UI核心组件Layout布局介绍:构建灵活高效的界面布局系统

在现代前端开发中&#xff0c;布局系统扮演着至关重要的角色&#xff0c;它不仅决定了界面的结构美感&#xff0c;更直接影响用户体验和开发效率。OneCode作为一款企业级低代码开发平台&#xff0c;其布局引擎通过精巧的设计实现了简洁API与强大功能的完美平衡。本文将深入剖析…

为何“白名单媒体”是性价比之选?

在信息媒体空前发展的今天&#xff0c;软文营销已成为企业品牌推广的重要手段之一。然而&#xff0c;面对众多媒体&#xff0c;如何选择高性价比的发稿媒体成为许多营销人员的一个课题。其中&#xff0c;“白名单媒体”凭借其高收录率、权威背书等优势&#xff0c;逐渐成为软文…

Python 异步编程之 async 和 await

基础知识 在 Python 中&#xff0c;async 和 await 是用于异步编程的关键字&#xff0c;引入了异步/协程&#xff08;coroutine&#xff09;的概念。核心思想是通过 协程&#xff08;Coroutine&#xff09; 和 事件循环&#xff08;Event Loop&#xff09; 实现非阻塞并发&…

关于接口测试的HTTP基础【接口测试】

HTTP 协议基础知识总结&#xff08;用于 Web API 接口测试&#xff09;接口测试中最常用的通讯协议就是 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#xff0c;本节旨在帮助理解 HTTP 协议的结构、工作流程以及如何用于接口测试。一、HTTP 协议简介HTTP 是一种…

STM32 DMA通信详解

STM32 DMA通信详解DMA(Direct Memory Access&#xff0c;直接内存访问)是STM32微控制器中一种重要的数据传输机制&#xff0c;它允许外设与内存之间或内存与内存之间直接传输数据&#xff0c;而无需CPU的干预。这种机制可以显著提高系统性能&#xff0c;特别是在需要高速数据传…

pytest--1--pytest-mock常用的方法

1. mocker.patch mocker.patch 是最常用的方法&#xff0c;用于替换指定的对象或方法。它可以用于模拟函数、方法、类或模块。 语法 mocker.patch(target, newDEFAULT, specNone, createFalse, spec_setNone, autospecNone, new_callableNone, **kwargs)示例 import pytest fro…

尚庭公寓----------分页查询

根据条件分页查询公寓列表 进行分页配置 package com.nie.lease.common.mybatisplus;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.in…

【图像质量评价指标】图像熵(Image Entropy) —— 熵值饱和现象

文章目录一、图像熵&#xff08;Image Entropy&#xff09;&#xff08;1&#xff09;基本原理&#xff08;2&#xff09;优势与局限&#xff08;3&#xff09;推荐策略多指标联合推荐体系噪声应对机制建议二、项目实战 —— 通过图像熵评价序列图像&#xff0c;并提取最优图像…

GaussDB in的用法

1 in的作用in运算符允许您在WHERE子句中指定多个值。 in运算符是多个OR条件的简写。2 in的语法select column_name(s) from table_name where column_name in (value1, value2, ...); 或者 select column_name(s) from table_name where column_name in (select statement);3 i…

【C语言进阶】内存函数

目录 1.memcpy函数 1.1 模拟实现 2.memmove函数 3.memcmp函数 1.memcpy函数 字符串拷贝strcpy和strncpy是有一定局限性的&#xff0c;只能拷贝字符串&#xff0c;而memcpy可以拷贝任意类型的数据&#xff0c;单位是字节。 1.1 模拟实现 #include<stdio.h> #include&l…

从乱序到整洁:Swift 实现奇偶链表重排的最佳方案

文章目录摘要描述题解答案题解代码分析分段讲解示例测试及结果时间复杂度空间复杂度总结摘要 在开发中&#xff0c;链表结构经常出现在缓存淘汰、操作系统任务调度、或是 LRU 算法中&#xff0c;尤其是对节点位置的灵活操作更是链表的强项。LeetCode 第 328 题「奇偶链表」就给…

WPF+CEF 执行JS报错

WPFCEF 执行JS报错 在WPF中执行 webBrowser.EvaluateScriptAsync(“window.scrollBy(0, 1000);”); 在部分网站会报异常&#xff1a; Request BrowserId : XXXX not found it’s likely the browser is already closed环境 .Net Framework 4.7 CefSharp.Wpf 131.3.50 解决方案&…

【Python3-Django】快速掌握DRF:ModelViewSet实战指南

DRF讲解 1. 什么是 Django 和 Django REST Framework&#xff1f; 在深入 ModelViewSet 之前&#xff0c;我们先简单了解一下背景知识&#xff1a; Django 是一个基于 Python 的 Web 开发框架&#xff0c;旨在帮助开发者快速构建安全、可扩展的 Web 应用。它遵循“不要重复自己…

TRAE IDE** 下载、安装、开发、测试和部署 2048 小游戏的全流程指南

以下是一份完整的 TRAE IDE 下载、安装、开发、测试和部署 2048 小游戏的全流程指南。整个过程基于 TRAE 作为 AI 辅助编程工具的特性&#xff08;对标 Cursor/AWS Kiro&#xff09;&#xff0c;假设它支持智能代码生成和云部署功能。 【插播】腾讯云AI Coding大赛https://mar…

重学前端005 --- 响应式网页设计 CSS 盒子模型

文章目录BOX 盒子概念CSSoverflow: hidden;filter: blur(3px);box-shadow: 0 0 3px 3px #efb762;border-radius: 30px 25px 60px 12px;transform: rotate(-0.6deg);每个 HTML 元素都是一个盒子&#xff0c;它拥有着自己的间距和边框。这叫作“盒子模型”。 BOX 盒子概念 内容…

TC500R立式加工中心主轴箱机械结构设计cad【11张】三维图+设计说明书

TC500R立式加工中心主轴箱机械结构设计 摘 要 数控机床作为工业制造的基础&#xff0c;在国家的发展中起着非常重要的作用。随着我国经济的快速发展&#xff0c;我国已经成为工业制造大国&#xff0c;制造业的发展离不开数控机床&#xff0c;而TC500R立式加工中心作为数控机床…

CSS Grid布局:构建现代网页的强大网格系统

目录 一、Grid布局基础概念 1.1 网格容器与网格项 1.2 创建基本网格 二、核心属性详解 2.1 定义网格轨道 2.2 网格间距控制 2.3 网格项对齐方式 三、实战布局技巧 3.1 创建经典布局 3.2 网格项定位技巧 3.3 响应式网格设计 四、Grid布局 vs Flexbox布局 五、高级…

Elasticsearch / MongoDB / Redis / MySQL 区别

1、一句话简介名称核心用途Elasticsearch强大的全文检索与日志分析引擎MongoDB灵活的文档数据库&#xff0c;适合半结构化/结构化数据Redis高性能的内存键值缓存数据库&#xff0c;用于实时高并发处理MySQL经典关系型数据库&#xff0c;强事务支持&#xff0c;结构化数据持久存…

网络通信之基础知识

一、什么是计算机网络&#xff1f;计算机网络是指由若干主机、通信链路和网络设备&#xff08;如路由器、交换机等&#xff09;组成的系统&#xff0c;借助通信协议&#xff0c;实现信息共享和资源互联。其本质是&#xff1a;多台设备之间通过协议进行数据交换。二、网络协议与…