【问题标题】:How to bind a BlockingCollection to a WPF Listivew如何将 BlockingCollection 绑定到 WPF 列表视图
【发布时间】:2019-08-19 16:02:22
【问题描述】:

我在 ViewModel 中定义了一个 BlockingCollection,它由不同的线程更新。我正在使用这个 BlockingCollection 来填充 ListView。但是这个集合中新添加的项目并没有反映在 UI 上。我需要一个 BlockingCollection,因为我正在进行一个多线程操作,这个集合可能由不同的线程更新,我想确保线程安全,因此决定使用 BlockingCollection

我的 ViewModel 是:

public BlockingCollection<WorklistItem> ListSource { get; set; }

在 xaml 中,我将此 BlockingCollection 设置为将列表视图填充为

 <ListView x:Name="MyList" HorizontalAlignment="Left" Height="263" Margin="5,200,0,0" VerticalAlignment="Top" Width="515" Grid.Column="0" AutomationProperties.IsColumnHeader="True" 
                              SelectedItem="{Binding SelectedItem}"
                              ItemsSource ="{Binding ListSource}" >

【问题讨论】:

  • 如果没有好的minimal reproducible example,就不可能提供好的答案。也就是说,BlockingCollection&lt;T&gt; 没有实现INotifyCollectionChanged,这是为了更新集合导致绑定的 UI 更新所必需的。恕我直言,您应该只使用ObservableCollection&lt;T&gt; 并明确管理线程安全。 Stack Overflow 上已经有很多问题解释了如何从后台线程更新ObservableCollection&lt;T&gt;

标签: c# wpf multithreading data-binding blockingcollection


【解决方案1】:

您最简单的方法是从 observablecollection 开始并添加锁定和同步。 Using BindingOperations.EnableCollectionSynchronization

如果您特别需要阻塞集合中的功能,那么您可以继承 observablecollection,实现 iproducerconsumercollection https://docs.microsoft.com/en-us/dotnet/api/system.collections.concurrent.iproducerconsumercollection-1?view=netframework-4.8,然后将新集合用作阻塞集合的基本类型。当你新建一个blockingcollection时,你可以给它一个底层的集合类型而不是默认的。如果您不知道,可以点击此链接并向下滚动https://docs.microsoft.com/en-us/dotnet/standard/collections/thread-safe/blockingcollection-overview

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多