List和ObservableCollection的转换
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 等
}
本文作者:孤沉
本文链接:https://www.cnblogs.com/guchen33/p/18106679
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)