Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WPF ObservableCollection未更新?_Wpf_Multithreading_Observablecollection - Fatal编程技术网

WPF ObservableCollection未更新?

WPF ObservableCollection未更新?,wpf,multithreading,observablecollection,Wpf,Multithreading,Observablecollection,似乎无法获取要更新的ObservableCollection。树视图显示为空。 错误:此类型的collectionview不支持从与dispatcher线程不同的线程更改其sourcecollection 类级变量 public ObservableCollection<TSItem> tsItems { get; set; } xaml 您应该将更改发送到UI线程: private void AddTreeViewItem(TSItem item) { Dispatc

似乎无法获取要更新的ObservableCollection。树视图显示为空。 错误:此类型的collectionview不支持从与dispatcher线程不同的线程更改其sourcecollection

类级变量

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


您应该将更改发送到UI线程:

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

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

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

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

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

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

作为使其正常工作的捷径,请考虑<代码>应用程序>分派器>调用< <代码> >或>代码>开始调用> /COD>。这需要引用PrimeTytCys。因此,如果您想对它进行超级纯的话,MVVM可能不太好。


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

  • 创建自己的INotifyCollectionChanged实现,该实现封装了一个
    SynchronizationContext
    ,并转发了一个内部
    observeCollection
  • 使用
    SynchronizationContext.Current
    获取构造函数中的
    SynchronizationContext
    。只有在UI线程上访问构造函数时,这才有效
  • SynchronizationContext
    传递给每个需要同步上下文的类
在更新可观察集合之前,您必须重新调用UI线程

作为使其正常工作的捷径,请考虑<代码>应用程序>分派器>调用< <代码> >或>代码>开始调用> /COD>。这需要引用PrimeTytCys。因此,如果您想对它进行超级纯的话,MVVM可能不太好。


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

  • 创建自己的INotifyCollectionChanged实现,该实现封装了一个
    SynchronizationContext
    ,并转发了一个内部
    observeCollection
  • 使用
    SynchronizationContext.Current
    获取构造函数中的
    SynchronizationContext
    。只有在UI线程上访问构造函数时,这才有效
  • SynchronizationContext
    传递给每个需要同步上下文的类

将TSItem切换到public类,同时将集合设置为public,并且仍然不使用此更新。我必须在与DependencyObjective相同的线程上创建DependencySource。我相信此错误与图像源的创建有关。如果动态创建位图图像,则应通过调用freeze()方法将其冻结。好的,我让它工作起来了,我需要在TSItemSwitched TSItem to public类中调用ImageSource上的Freeze(),同时使集合成为公共的,并且仍然不使用它更新。我必须在与DependencyObjective相同的线程上创建DependencySource。我相信这个错误与您的图像源创建有某种关系。如果动态创建位图图像,则应通过调用freeze()方法将其冻结。好的,我让它工作了,我需要在TSItem中调用ImageSource的Freeze(),你真的启动了后台工作程序吗?我无法复制你的问题。是的,更新了帖子。工作进程是在加载的事件中启动的。tsItems应该是公共的…您确实启动了后台工作进程吗?我无法复制你的问题。是的,更新了帖子。工作进程是在加载的事件中启动的。tsItems应该是公共的…是否有方法在不在UI线程上的情况下更新它?我需要用户在树视图中看到它的进度,因为它正在工作?这是否需要我为每个任务创建一个worker,然后在完成时更新它?有没有一种方法可以在不在UI线程上的情况下更新它?我需要用户在树视图中看到它的进度,因为它正在工作?这是否需要我为每个任务创建一个worker,然后在完成时更新它?
<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>
 private void AddTreeViewItem(TSItem item)
 {
    Dispatcher.BeginInvoke(new Action(() => tsItems.Add(item)));
 }