首页 > 其他分享 >List和ObservableCollection的转换

List和ObservableCollection的转换

时间:2024-03-31 14:12:39浏览次数:24  
标签:OnCollectionChanged ObservableCollection 转换 Invoke List 线程 UI Dispatcher

1、我们后台查询全部List数据的时候,前台需要ObservableCollection展示
这个时候List需要转换成ObservableCollection

 public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> source)
 {
     if (source == null)
     {
         throw new ArgumentNullException("source");
     }
     return new ObservableCollection<T>(source);
 }

2、但是这会出现一个问题,假如我们使用的异步查询

  var asideMenus = await _asideMenuService.QueryListAsync();
  AsideMenus = asideMenus.ToObservableCollection();

此时AsideMenus为空,这是因为asideMenus是在后台查询到的,即使你转化成了ObservableCollection它还没有更新到UI
3、解决方法
解决1、需要使用Foreach,ForEach 是 LINQ 中的一个扩展方法,它遍历集合中的每个元素并对其执行指定的操作。当您在 UI 线程上调用 ForEach 时,它将直接更新 ObservableCollection,并且 CollectionChanged 事件将被触发,从而使 UI 得到更新

(await _asideCreateControlService.QueryListAsync()).ForEach(x => PlayListInputDtos.Add(x));

解决2、使用Dispatcher,WPF 使用 Dispatcher 来管理线程间的操作。当您从后台线程调用 Dispatcher.Invoke 或 Dispatcher.BeginInvoke 时,您实际上是在请求 UI 线程稍后执行指定的操作。这对于更新 UI 控件和集合是必要的,因为 WPF 要求这些操作必须在创建它们的线程上执行

  foreach (var menu in await _asideMenuService.QueryListAsync())
  {
      Dispatcher.CurrentDispatcher.Invoke(() => AsideMenus.Add(menu));
  }

解决3、但是当你操作大量UI时,通过减少 Dispatcher.Invoke 的调用次数,您可以减少线程创建和管理的开销,从而提高性能。在这种情况下,您可以先在后台线程中收集所有数据,然后在 UI 线程上一次性更新 ObservableCollection

  foreach (var menu in await _asideMenuService.QueryListAsync())
  {
      Application.Current.Dispatcher.Invoke(() => AsideMenus.Add(menu));
  }

解决4、是对解决3的扩展,重写OnCollectionChanged方法

 public class ThreadSafeObservableCollection<T> : ObservableCollection<T>
 {
     public ThreadSafeObservableCollection()
     {
         
     }
     public ThreadSafeObservableCollection(IEnumerable<T> list) : base(new List<T>(list ?? throw new ArgumentNullException(nameof(list))))
     {
     }
     protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
     {
         // 确保 CollectionChanged 事件在 UI 线程上触发
         if (Thread.CurrentThread.ManagedThreadId == Dispatcher.CurrentDispatcher.Thread.ManagedThreadId)
         {
             base.OnCollectionChanged(e);
         }
         else
         {
             Dispatcher.CurrentDispatcher.Invoke(() => base.OnCollectionChanged(e));
         }
     }

     // 其他需要重写的 OnCollectionChanged 相关方法,如 OnAddingNew, OnRemoved, OnReplaced 等
 }

标签:OnCollectionChanged,ObservableCollection,转换,Invoke,List,线程,UI,Dispatcher
From: https://www.cnblogs.com/guchen33/p/18106679

相关文章

  • 类数组对象转换为数组
    <!--HTML结构--><olid="test-list"><liclass="lang">Scheme</li><liclass="lang">JavaScript</li><liclass="lang">Python</li><liclass="lang&......
  • 【c++】类和对象(六)深入了解隐式类型转换
    ......
  • WinForm 程序中控件坐标之间的转换
    控件坐标系和屏幕坐标系之间的转换:如果要将一个控件上的点(例如Label或Button)的坐标(x,y)转换为屏幕上的点(x1,y1),可以使用Control.PointToScreen方法。例如:PointcontrolPoint=newPoint(x,y);PointscreenPoint=control1.PointToScreen(controlPoint);屏幕坐标......
  • .Net 对象与对象之间的映射转换的6中方式以及性能对比
    我们在.Net开发的过程中,经常会遇到一个实体对象与另一个实体对象之间的映射转换,接下来我们将依次去实现6个对象间映射转换的方式,并对他们进行性能测试,找出其中效率最高的方式。通过对象Copy,通过new一个新的实体对象通过手动赋值的方式实现publicclassObjectCopyMapper{......
  • 监听器 Listener
    目录1、什么是Listener 2、在Web中的重要作用3、怎样使用4、在不同层面的应用1)JavaScript事件监听:2)Web框架中的监听器:3)应用服务器和容器中的监听器:区别:1、什么是Listener Listener是计算机科学中的一个重要概念,用于监视和响应特定事件的发生。在Web中,监听器的作......
  • C语言中char字符型数据的存取形式:ASCII码之间的转换
    unsignedcharchannelNum=49;则编译器会将ASCII码49存入变量channelNum,实际channelNum表示字符1,所以下次如果以%c形式打印出来,则输出1。e.g:查看代码unsignedcharchannelNum=49;#include"bsp_seg.h"#include"bsp_Init.h"//------------------------------------//将s......
  • LabelConvert: 目标检测和图像分割数据集格式转换工具
    LabelConvertLabelConvert是一个目标检测和图像分割的数据集格式转换工具,支持labelme、labelImg与YOLO、VOC和COCO数据集格式之间的相互转换。支持的转换格式安装pipinstalllabel_convert具体使用方法由于文章篇幅所限,请移步LabelConvert官方文档:docs......
  • python 3 : list 与 深copy/浅copy
    按语:               之前,论述了python可变数据类型与不可变数据类型。        这里继续补丁list与深copy/浅copy。               这里补充一下,深copy/浅copy是python宇宙中最离奇的存在!       令99%的小白求生不......
  • Django中values()和values_list()
    values()1、不带参数,返回所有属性的键值对,比如使用filter时,会返回一个列表,列表中每一项是一个字典>>>Blog.objects.values()[{'id':1,'name':'BeatlesBlog','tagline':'AllthelatestBeatlesnews.'}],>>>Blog.objects.filte......
  • 兼容模式下导致数值类型发生隐式转换,SQL在生产上无法正常使用案例
    兼容模式下导致数值类型发生隐式转换,SQL在生产上无法正常使用案例本文出处:https://www.modb.pro/db/403148基于MogDB版本V2.0.1问题现象厂商研发描述InsertSQL在生产上无法执行,而测试环境中同版本的数据库该SQL可以正常运行。检查SQL后,发现是很简单的insertinto......