C#中使用Threads和ListView的问题
我有一个文本过滤器,在 TextChanged 事件中我以这种方式启动列表视图填充代码:
ThreadPool.QueueUserWorkItem(new WaitCallback(populate));
然后在填充方法中我有这样的代码,
listView1.BeginUpdate();
listView1.Clear();
// rest of the code
listView1.EndUpdate();
但 listView1.BeginUpdate() 调用给出以下异常:
System.NotSupportedException was unhandled
Message="An error message cannot be displayed because an optional resource assembly containing it cannot be found"
StackTrace:
at Microsoft.AGL.Common.MISC.HandleAr()
at System.Windows.Forms.ListView.ntvSetStyleEx()
at System.Windows.Forms.ListView.BeginUpdate()
at App.frmSelectClient.populate()
at WorkItem.doWork()
at System.Threading.Timer.ring()
InnerException:
我做错了什么?
我想在后台线程中发出 ListView 的填充。
I have a text filter where in the TextChanged event I launch a listview populate code this way:
ThreadPool.QueueUserWorkItem(new WaitCallback(populate));
Then in the populate method I have code like this
listView1.BeginUpdate();
listView1.Clear();
// rest of the code
listView1.EndUpdate();
but the listView1.BeginUpdate() call gives the following exception:
System.NotSupportedException was unhandled
Message="An error message cannot be displayed because an optional resource assembly containing it cannot be found"
StackTrace:
at Microsoft.AGL.Common.MISC.HandleAr()
at System.Windows.Forms.ListView.ntvSetStyleEx()
at System.Windows.Forms.ListView.BeginUpdate()
at App.frmSelectClient.populate()
at WorkItem.doWork()
at System.Threading.Timer.ring()
InnerException:
What I am doing wrong?
I would like to issue the populate of the ListView in a background thread.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法从 UI 线程以外的任何线程更新 UI 元素。使用 Control.Invoke/BeginInvoke 来执行此操作。
您可以在后台线程中完成所有数据加载等操作,但您需要编组到 UI 线程以实际填充 UI 控件本身。
大多数 UI 框架都是这种情况 - 当然还有 Windows Forms(桌面和 CF)和 Windows Presentation Foundation(您使用 Dispatcher 而不是 Control.Invoke/BeginInvoke)。
需要注意的一点是:如果我没记错的话,Compact Framework 仅支持 Control.Invoke/BeginInvoke 的 EventHandler 委托。诚然,这在最近的版本中可能已经改变。
You can't update UI elements from any thread other than the UI thread. Use Control.Invoke/BeginInvoke to do this.
You can do all your data loading etc in the background thread, but you'll need to marshal to the UI thread to actually populate the UI controls themselves.
This is the case in most UI frameworks - and certainly Windows Forms (desktop and CF) and Windows Presentation Foundation (where you use a Dispatcher rather than Control.Invoke/BeginInvoke).
One point to note: if I remember rightly, the Compact Framework only supports the EventHandler delegate for Control.Invoke/BeginInvoke. That may have changed in more recent versions, admittedly.
就像其他帖子中提到的从另一个线程更新 ListView 一样,您必须使用 BeginInvoke/Invoke 以正确的方式执行此操作。我为自己创建了几个线程安全的辅助函数(对于 ListView 和更多控件)。每当我想用列表视图或控件本身做某事时,我只使用下面提到的其中之一。当然,它错过了很多其他选项,但到目前为止我还不需要其他选项,所以我没有创建更多选项,但它应该向您展示最终将它们添加到列表中的正确方法。
用法很简单:GlobalFunctions.listViewClearItems(yourListView);
编辑:我错过了紧凑框架标签,所以不确定这是否适用于它。你应该有人能够证实这一点。
Like it was mentioned in other posts to update ListView from another thread you have to do it the proper way using BeginInvoke/Invoke. I've created for myself couple of helper functions that are thread safe (for both ListView and more Controls). Whenever i wanna do something with listview or control itself i just use one of those mentioned below. Of course it misses a lot of other options but so far I haven't had a need for something else so i didn't created more, but it should show you the right way to eventually add them up to the list.
Usage is simple: GlobalFunctions.listViewClearItems(yourListView);
Edit: i have missed compact framework tag so not sure this is applicable to it. Someone should be able to confirm it thou.