2013-07-29 4 views
1

Я пытаюсь настроить ListBox, который получает его данные из CollectionViewSource. Я хочу, чтобы, когда я обновляю базовый источник данных, ListBox также обновляется. Моя Xaml выглядит так ...Observable CollectionViewSource

<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 было предоставление сортировки в список на основе свойства в базовых объектах.

+1

Используйте ObservableCollection. – Nitesh

+0

После публикации этого сообщения я также прочитал, что CollectionViewSource не видит изменений. Это правильно и может ли это повлиять на то, что я делаю? – Remotec

+0

Нет, это неправда. «CollectionViewSource» прослушивает коллекцию, если ее использует исходная коллекция. –

ответ

4

Чтобы увидеть изменения, внесенные в саму коллекцию (например, добавление и удаление элементов), сбор должен реализоваться. INotifyCollectionChanged (ObservableCollection - базовая реализация этого интерфейса). Чтобы увидеть изменения, внесенные в элементы коллекции (например, изменение определенного свойства для определенного элемента), ваш объект объекта должен реализовать INotifyPropertyChanged.

CollectionViewSource - это слой между пользовательским интерфейсом и фактической коллекцией, который обеспечивает некоторый дополнительный контроль над отображением коллекции (сортировка, фильтрация, группировка и т. Д.). Он только передает уведомления в пользовательский интерфейс, если базовые данные поддерживают уведомления (путем реализации интерфейсов, упомянутых выше).

+0

Это работа и изменения, внесенные в свойство 'TestName' для базовых объектов, обновляющих штрафы. Однако изменение свойства «Приоритет», список которого сортируется, не вызывает автоматической повторной сортировки списка. Возможно, это невозможно. – Remotec

+0

Не имеет смысла прибегать к каждой смене недвижимости. Поскольку a) после изменения свойства в ui измененная строка может мгновенно перемещаться где-то, что убивает удобство использования, b) постоянная сортировка влияет на производительность. Если вам абсолютно необходимо прибегнуть к изменениям свойств, вы можете просто подписаться на событие «Свойство» для ваших элементов и вызвать 'cvs.View.Refresh()' в обработчике событий. –

+0

Я должен был упомянуть - у пользователя не будет возможности изменить порядок сортировки.Эта функциональность такова, что неудачные тесты могут быть перенесены в верхнюю часть программы. Возможно, ListBox не является в конечном итоге лучшим инструментом для этой работы. – Remotec

1

Я подозреваю, что вы используете List<T> вместо ObservableCollection<T> как underlying source collection для вашего CollectionViewSource.

ICollectionView предоставит вам filter, sort, or group сборник вместе с распространением INotifyCollectionChanged событий, если базовая коллекция реализует его.

Кроме того, в случае, если вы хотите refresh своей коллекции, когда любой property change в T классе вы должны вручную вызвать Refresh вашей коллекции или можете использовать ICollectionViewLiveShaping введенные в .Net4.5.

Смотрите мой ответ здесь для обоих подходов - Automatically Refresh ICollectionView

Смежные вопросы