【问题标题】:Observable CollectionViewSource可观察的 CollectionViewSource
【发布时间】:2013-07-28 22:41:12
【问题描述】:

我正在尝试设置一个从 CollectionViewSource 获取数据的 ListBox。我想要发生的是,当我更新基础数据源时,ListBox 也会更新。我的 Xaml 看起来像这样...

<Window.Resources>
    <ObjectDataProvider x:Key="AppTests" ObjectType="{x:Type Application:AppTestProvider}" MethodName="GetAppTests" />
    <CollectionViewSource x:Key="cvs" Source="{StaticResource AppTests}">
        <CollectionViewSource.SortDescriptions>
            <scm:SortDescription PropertyName="Priority" Direction="Ascending" />
        </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
</Window.Resources>

<Grid>
    <ListBox x:Name="TestList" ItemsSource="{Binding Source={StaticResource cvs}}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding TestName}" />                    
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

这可以很好地显示数据,但是如果我更改了基础数据,那么在我调用后面代码中的 cvs.View.Refresh() 方法之前,这些更改不会出现在网格上。

我怎样才能使这个“可观察”,以便自动发生变化?

注意:使用 CVS 的原因是根据底层对象中的属性对列表进行排序。

【问题讨论】:

  • 使用 ObservableCollection。
  • 发布后我还读到 CollectionViewSource 没有观察到变化。这是正确的吗?这会影响我的工作吗?
  • 不,这不是真的。 CollectionViewSource 如果底层源集合实现它,则侦听 Collection 已更改。
  • @RohitVats,从某种意义上说,CollectionViewSource自己不会观察到变化。它不会创建通知事件,而只是将它们转发到 UI 层。
  • @Nikita - 是的,这也是我在回答中写的 - It propagate INotifyCollectionChanged events if the underlying collection implements it.

标签: c# .net wpf xaml data-binding


【解决方案1】:

要查看对集合本身所做的更改(例如添加和删除项目),集合应实现 INotifyCollectionChangedObservableCollection 是此接口的基本实现)。要查看对集合中的项目所做的更改(例如修改特定项目的特定属性),您的项目对象应实现 INotifyPropertyChanged

CollectionViewSource 是 UI 和实际集合之间的一层,它为集合的显示方式(排序、过滤、分组等)提供了一些额外的控制。如果底层数据支持通知(通过实现上述接口),它只会将通知传递给 UI。

【讨论】:

  • 这是有效的,对基础对象的 TestName 属性所做的更改会更新罚款。但是,更改列表排序依据的Priority 属性不会导致列表自动重新排序。也许这无论如何都是不可能的。
  • 对每个属性都进行更改是没有意义的。因为 a) 在 ui 修改行中修改属性后可能会立即移动到某个地方,这会破坏可用性,b) 常量排序会影响性能。如果您绝对需要更改属性 - 您可以简单地订阅您的项目的 PropertyChanged 事件并在事件处理程序中调用 cvs.View.Refresh()
  • 我应该提到 - 用户将无法更改排序顺序。此功能使程序可以将失败的测试移到顶部。也许 ListBox 最终并不是完成这项工作的最佳工具。
【解决方案2】:

我怀疑您使用List&lt;T&gt; 而不是ObservableCollection&lt;T&gt; 作为underlying source collectionCollectionViewSource

ICollectionView 将使您能够filter, sort, or group 集合以及传播INotifyCollectionChanged 事件(如果基础集合实现它)。

此外,如果您想在T 类中的任何property change 中使用refresh 您的收藏,您必须手动调用您收藏的Refresh,或者可以使用.Net4.5 中引入的ICollectionViewLiveShaping

请参阅我的回答以了解这两种方法 - Automatically Refresh ICollectionView

【讨论】:

    猜你喜欢
    • 2019-09-09
    • 2011-06-09
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    相关资源
    最近更新 更多