这是我在从ThreadPool获取的单独线程中向ObservableCollection添加项目的方法。
我们知道它会引发异常:
This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.
我知道这个主题在这里很受欢迎,但我没有找到任何适合下面代码中描述的情况的解决方案:
namespace WpfApplication1
{
class Item
{
public string name
{
get;
set;
}
}
class Container
{
public ObservableCollection<Item> internalList = new ObservableCollection<Item>();
}
public partial class MainWindow : Window
{
Container container = new Container();
void addItems()
{
Item item = new Item() { name = "jack" };
container.internalList.Add(item);
}
public MainWindow()
{
InitializeComponent();
ThreadPool.QueueUserWorkItem(delegate { this.addItems(); });
MyDataGrid.ItemsSource = container.internalList;
}
}
}
这个问题的最佳解决方案是什么?
谢谢!
答案 0 :(得分:3)
替换
container.internalList.Add(item);
通过
Dispatcher.BeginInvoke(new Action(() => container.internalList.Add(item)));
这样Add
在Dispatcher
线程上执行。
答案 1 :(得分:1)
您可以将后台主题中的数据作为List
,然后将此列表转换为ObservableCollection
,如下所示
List<SomeViewModel> someViewModelList = await GetYourDataAsListAsync();
ObservableCollection<SomeViewModel> Resources = new TypedListObservableCollection<SomeViewModel>(someViewModelList);
我希望这会有所帮助。
答案 2 :(得分:1)
确保在UI线程上设置UI对象的属性:
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
{
MyDataGrid.ItemsSource = container.internalList;
});
这会将大括号内的代码添加到UI线程Dispatcher
的工作项队列中。
答案 3 :(得分:1)
问题不在您的类的Collection中,而是在从UI Thread绑定到此集合的Control中。
WPF 4.5中有一些新功能: http://www.jonathanantoine.com/2011/09/24/wpf-4-5-part-7-accessing-collections-on-non-ui-threads/
//在某处创建锁定对象
private static object _lock = new object();
//启用其他地方对此集合的交叉访问
BindingOperations.EnableCollectionSynchronization(_persons, _lock);
MSDN: http://msdn.microsoft.com/en-us/library/hh198845(v=vs.110).aspx