WPF ObservableCollection没有更新?

时间:2013-12-02 14:29:33

标签: wpf multithreading observablecollection

似乎无法更新ObservableCollection。 TreeView显示为空。 错误:这种类型的collectionview不支持从与调度程序线程不同的线程更改其sourcecollection。

班级变量

public ObservableCollection<TSItem> tsItems { get; set; }

初始化组件

tsItems = new ObservableCollection<TSItem>();
bwRun.DoWork += bwRun_DoWork;
InitializeComponent();
tvTest.ItemsSource = tsItems;
来自后台工作者的

我使用以下方法添加到集合

 private void AddTreeViewItem(TSItem item)
 {
     tsItems.Add(item);
 }

XAML

<TreeView x:Name="tvTest" HorizontalAlignment="Left" Height="249" Margin="140,36,0,0" VerticalAlignment="Top" Width="257">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Image Source="{Binding Icon}" />
                    <TextBlock Text="{Binding Header}" />
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

3 个答案:

答案 0 :(得分:2)

您应该将更改分派给UI线程:

 private void AddTreeViewItem(TSItem item)
 {
    Dispatcher.BeginInvoke(new Action(() => tsItems.Add(item)));
 }

答案 1 :(得分:1)

在更新可观察集合之前,重新调用UI线程。

作为让其正常工作的快捷方式,请考虑Application.Dispatcher.InvokeBeginInvoke。这需要引用PresentationCore,因此对于MVVM可能不太好你想成为超级纯粹的


如果你想以某种方式变得更纯洁,你需要做更多的工作。其中大部分涉及捕获UI线程的SynchronizationContext

  • 创建自己的INotifyCollectionChanged实现,它包装SynchronizationContext并转发内部ObservableCollection的事件
  • 使用SynchronizationContext在构造函数中抓取SynchronizationContext.Current。这仅适用于在UI线程上访问构造函数的情况。
  • SynchronizationContext传递给每个需要的课程。

答案 2 :(得分:0)

@Somedust是正确的。我还要补充一点,你说你正在通过后台工作者更新可观察的集合。如果您这样做,则需要确保在执行此操作时返回UI线程。