2012-10-14 18 views
7

这里就是我有 - 用的ItemsSource列表框设置为ObservableCollection<T> - 其中T是我代表一个文件自定义类,只包含2 DependencyProperties:文件名和ThumbnailPath。 - 该列表框还具有定义的自定义DataTemplate,以便在其下方很好地显示图像和文件名。异步增加的ObservableCollection(或替代)

列表框的目的是为了显示在当前文件夹(在一个TreeView选择的)的视频文件,与缩略图(异步生成;不此问题的一部分)。

所以,当我改变文件夹在树视图中,是的ObservableCollection清除并重新填满,这是自动反映在ListBox中的项目。

这里的问题:用户界面变得没有反应,它需要长达几秒钟更新。再次,缩略图在这里没有意义(我试图禁用它们)。 我觉得什么花费时间最多的是我的自定义类,以及它们的视觉表现的50-100实例建设 - 它必须初始化为每一个Image对象。但这只是我的猜测 - 你能否确认或排除这种可能性?

我开始觉得的ObservableCollection可能不会去这里,因为从我读的方式,从我试用了一下,有没有办法来添加项目异步,至少如果这些项目DependencyObjects。我尝试使用BackgroundWorker创建我的类实例,并将它们添加到ProgressChanged事件处理程序中的集合中,但它会引发异常(某些线程vs依赖对象问题)。

有没有办法,我失去了一些东西?或者我可以通过简单地放弃ObservableCollection并编写一个很好的旧异步for循环来添加项目?

+1

什么是确切的异常类型和消息? – Adam

+0

“必须在DependencyObject的同一线程上创建DependencySource” –

+0

'Binding,IsAsync = True'怎么办? –

回答

12

由于您的ObservableCollection绑定到UI,因此它会在UI线程上生成,因此任何进一步的更新(删除/添加/清除)必须位于同一UI线程上。它不允许来自另一个线程的更新。

不过,你所能做的就是创建类的insance(或全部耗时在后台线程操作),一旦完成后,用你的UI线程的Dispatcher像这样的ObservableCollection添加的对象 -

App.Current.Dispatcher.BeginInvoke((Action)delegate() 
          { 
           observableCollection.Add(instanceOfYourClass); 
          }); 

什么Dispatcher要做的就是把它相关的线程上运行。因此,该项目将始终添加在UI线程上,但可以在后台线程中创建。

这里有可能让你去几个环节 - Updating from BW等一个here

+0

谢谢,我会试试看,我一定会看看这篇有趣的文章,但是我尝试了一些类似的东西(现在找不到它),但没有运气......我觉得我的课是一个问题, DependencyObject的。就像“你不能在一个线程上创建一个dependencyobject并在另一个线程上使用它”。 –

+0

是的,您的DP必须在UI线程本身上创建。如果你想绑定到你的用户界面,你必须使用DP的,但如果没有,我会建议寻求简单的'POCO'属性实现'INPC'界面。 –

+0

我想绑定它...我需要列表框来显示我的FILE类实例的列表,并应用了我的自定义数据模板。我想我会和INPC一起去。 –

5

使用.NET 4.5,您可以使用EnableCollectionSynchronization

object lockObj = new object(); 
     BindingOperations.EnableCollectionSynchronization(yourObservableCollection, lockObj);