我有这个:
我尝试在BackgroundWorker的Completed事件中更新UI,使用Dispatcher,使用DispatchTimer ...所有这些都显示用户控件,但ObservableCollection仍无法用于添加。
尝试将项添加到集合的代码位于UserControl内。
确切的错误是:“这种类型的CollectionView不支持从与Dispatcher线程不同的线程更改其SourceCollection ”
如果我不在后台加载,就不会发生这种情况。
感谢您为此提供的任何解决方法。
换句话说,我想做的是在后台处理UI线程中创建一个对象......我知道这可能听起来很傻。
答案 0 :(得分:1)
您可能需要查看您使用的是哪个Dispatcher
?在您的情况下,您可能指的是两个不同的调度员。
答案 1 :(得分:1)
通常我会在我的UI线程上创建对象,然后用从后台线程获得的数据填充它们。
例如,
void async LoadButton_Clicked(object sender, EventArgs e)
{
MyCollection = new ObservableCollection<SomeItem>();
// Can also use a BackgroundWorker
var collectionData = await GetCollectionData();
foreach(var item in collectionData)
{
MyCollection.Add(item);
}
}
我正在使用C#5.0 async
和await
关键字进行异步操作,但您也可以使用BackgroundWorker
来完成后台工作。
您还可以使用Dispatcher.BeginInvoke()
进行更轻松的后台工作(例如将数据复制到MyCollection
),但是对于繁重的工作,我发现它仍然会锁定UI,因此我更喜欢使用后台线程。
答案 2 :(得分:0)
如果视图绑定到此集合,则无法在单独的线程上修改ObservableCollection的内容,而是可以覆盖ObservableCollection并为其提供支持并在整个应用程序中使用它。
此示例包含您想要的内容 - http://tomlev2.wordpress.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/
答案 3 :(得分:0)
当谈到线程和ui元素时,最重要的遵循的规则之一可能会让你在长期运行中遇到很多麻烦,就是在ui-thread上保持ui-element实例化。当然你可以管理它。如果您需要从另一个线程更改这些对象,您可以使用Dispatcher。
(threading model引用也可能有意义)
答案 4 :(得分:0)
谢谢大家的帮助......一位来自MS的人访问了公司(对于商业注释感到抱歉)做其他事情,我把他收起来并展示了这种行为。在2分钟内找到了问题的根源......我不太确定。
碰巧我正在使用ICollectionView来显示我有问题的ObservableCollection的排序/过滤版本。我在我的类的构造函数中创建了这个ICollectionView,所以在反序列化时它是在另一个线程中创建的。他建议在代码中将此创建移动到更长的时间(当相关属性被读取时)。这解决了这个问题。
然而,在其他线程中创建的ObservableCollection现在允许我添加新项目。不知道为什么,但现在它有效。
很抱歉这么晚,再次感谢你。