当前位置:网站首页>解决 WPF 绑定集合后数据变动界面却不更新的问题
解决 WPF 绑定集合后数据变动界面却不更新的问题
2020-11-06 21:30:00 【程序猿欧文】
解决 WPF 绑定集合后数据变动界面却不更新的问题
独立观察员 2020 年 9 月 9 日
在 .NET Core 3.1 的 WPF 程序中打算用 ListBox 绑定显示一个集合(满足需求即可,无所谓什么类型的集合),以下是 Xaml 代码(瞟一眼就行,不是本文讨论重点):
<ListBox ItemsSource="{Binding SipRegistrations, Mode=OneWay}" SelectedValue="{Binding SelectedAccountBinding, Mode=OneWayToSource}"> <ListBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding SIPAccount.SIPUsername}"></TextBlock> </DataTemplate> </ListBox.ItemTemplate></ListBox>
ViewModel 中有一个目标集合,当前是一个 List。
属性变动通知有两种实现方式,一是使用 PropertyChanged.Fody,二是使用自定义绑定基类 BindableBase,如下图。
下面主要谈论数据变动(集合增加内容)后,前台的界面却没有更新的问题。具体来说就是,List.Add 之后,第一次有效果,但后面就没效果了,界面始终只显示一条数据。
原始(无效果):
SipRegistrations.RemoveAll(x => x.SIPAccount.SIPUsername == sipAccount.SIPUsername); // 移除重复项(如果有的话)SipRegistrations.Add(binding); // 添加新项
猜想是因为 List 的引用并没有变化,所以被认为该属性没有改变,进而也就没有变动通知。
其实这种需要变动通知的情况,推荐使用的是 ObservableCollection:
但是本人之前使用 ObservableCollection 没有成功过,反而是使用 List 是可以的,所以还是先看看用 List 怎么解决吧。
变体一(调试时有几率有效果):
//添加联系人到集合并处理界面绑定;SipRegistrations.RemoveAll(x => x.SIPAccount.SIPUsername == sipAccount.SIPUsername);List<SIPAccountBinding> tempList = SipRegistrations; //临时集合;SipRegistrations = new List<SIPAccountBinding>(); //目标集合先置为空;tempList.Add(binding); //临时集合添加新项;SipRegistrations = tempList; //临时集合赋值给目标集合;
变体一通过临时变量做中转,强制让目标集合(的引用)发生改变,但结果是只在调试时以很小的概率成功过。
由于这部分代码是在异步逻辑里,所以有可能是在多线程环境,而 List 不是线程安全的,所以有了以下加锁版本的变体二。
变体二(无效果,应该是和变体一类似):
#region 成员/// <summary>/// 加锁对象/// </summary>private object _lockObj = new object();#endregion//加锁;lock (_lockObj){ //添加联系人到集合并处理界面绑定; SipRegistrations.RemoveAll(x => x.SIPAccount.SIPUsername == sipAccount.SIPUsername); List<SIPAccountBinding> tempList = SipRegistrations; SipRegistrations = new List<SIPAccountBinding>(); tempList.Add(binding); SipRegistrations = tempList;}
加了锁还是不行(不过锁还是需要的),又想到,既然调试的时候有几率成功,那么是不是和代码运行速度有关呢?于是在目标集合置空和重新赋值之间加了个线程休眠,竟然真的可以,也就是以下的变体三。
变体三(有效果):
lock (_lockOb.........
版权声明
本文为[程序猿欧文]所创,转载请带上原文链接,感谢
https://my.oschina.net/mikeowen/blog/4554937
边栏推荐
- 嘉宾专访|2020 PostgreSQL亚洲大会阿里云数据库专场:王涛
- Xmppmini project details: step by step from the principle of practical XMPP technology development 4. String decoding secrets and message package
- 游戏主题音乐对游戏的作用
- 只有1个字节的文件实际占用多少磁盘空间
- What knowledge do Python automated testing learn?
- 华为云微认证考试简介
- Interpretation of Cocos creator source code: engine start and main loop
- MongoDB与SQL常用语法对应表
- Wechat applet: prevent multiple click jump (function throttling)
- Our best practices for writing react components
猜你喜欢
【自学unity2d传奇游戏开发】如何让角色动起来
Building and visualizing decision tree with Python
用一个例子理解JS函数的底层处理机制
如何在终端启动Coda 2中隐藏的首选项?
StickEngine-架构11-消息队列(MessageQueue)
【:: 是什么语法?】
What are the common problems of DTU connection
With the advent of tensorflow 2.0, can pytoch still shake the status of big brother?
Ronglian completed US $125 million f round financing
StickEngine-架构12-通信协议
随机推荐
Basic usage of GDB debugging
Use modelarts quickly, zero base white can also play AI!
What if the front end doesn't use spa? - Hacker News
How to turn data into assets? Attracting data scientists
Flink的DataSource三部曲之一:直接API
[actual combat of flutter] pubspec.yaml Configuration file details
使用 Iceberg on Kubernetes 打造新一代雲原生資料湖
2020年第四届中国 BIM (数字建造)经理高峰论坛即将在杭举办
What are the criteria for selecting a cluster server?
【转发】查看lua中userdata的方法
Humor: hacker programming is actually similar to machine learning!
Free patent download tutorial (HowNet, Espacenet)
開源一套極簡的前後端分離專案腳手架
Lane change detection
百万年薪,国内工作6年的前辈想和你分享这四点
Three Python tips for reading, creating and running multiple files
只有1个字节的文件实际占用多少磁盘空间
如何对数据库账号权限进行精细化管理?
Simple summary of front end modularization
html+vue.js 實現分頁可相容IE