Автоматическое обновление фильтра ICollectionView
Есть ли способ автоматического обновления фильтра на ICollectionView
без вызова Refresh()
, когда было сделано соответствующее изменение?
У меня есть следующее:
[Notify]
public ICollectionView Workers { get; set; }
Атрибут [Notify] в этом свойстве реализует только INotifyPropertyChanged
, но в этой ситуации он ничего не делает.
Workers = new CollectionViewSource { Source = DataManager.Data.Workers }.View;
Workers.Filter = w =>
{
Worker worker = w as Worker;
if (w == null)
return false;
return worker.Employer == this;
};
В XAML:
<TextBlock x:Name="WorkersTextBlock"
DataContext="{Binding PlayerGuild}"
FontFamily="Pericles"
Text="{Binding Workers.Count,
StringFormat=Workers : {0},
FallbackValue=Workers : 99}" />
Обновление: Похоже, что использование ICollectionView
будет необходимо для меня, поэтому я хотел бы вернуться к этой теме. Я добавляю щедрость к этому вопросу, получателем которого будет любой человек, который может дать некоторое представление о том, как реализовать "hands-off" ICollectionView
, который не нужно обновлять вручную. На данный момент я открыт для любых идей.
Ответы
Ответ 1
AFAIK нет встроенной поддержки в ICollectionView
для обновления коллекции при любом изменении свойства в исходной коллекции.
Но вы можете подклассифицировать ListCollectionView
, чтобы придать его собственной реализации refresh collection on any property changed
. Образец -
public class MyCollectionView : ListCollectionView
{
public MyCollectionView(IList sourceCollection) : base(sourceCollection)
{
foreach (var item in sourceCollection)
{
if (item is INotifyPropertyChanged)
{
((INotifyPropertyChanged)item).PropertyChanged +=
(s, e) => Refresh();
}
}
}
}
Вы можете использовать это в своем проекте следующим образом:
Workers = new MyCollectionView(DataManager.Data.Workers);
Это можно использовать повторно в своем проекте, не беспокоясь об обновлении коллекции на каждом PropertyChanged
. MyCollectionView
сделает это automatically
для вас.
ИЛИ
Если вы используете .Net4.5, вы можете пойти с реализацией ICollectionViewLiveShaping
, как описано здесь.
Я разместил часть реализации для вашей проблемы здесь - Внедрение ICollectionViewLiveShaping.
Рабочий код из этого сообщения -
public ICollectionViewLiveShaping WorkersEmployed { get; set; }
ICollectionView workersCV = new CollectionViewSource
{ Source = GameContainer.Game.Workers }.View;
ApplyFilter(workersCV);
WorkersEmployed = workersCV as ICollectionViewLiveShaping;
if (WorkersEmployed.CanChangeLiveFiltering)
{
WorkersEmployed.LiveFilteringProperties.Add("EmployerID");
WorkersEmployed.IsLiveFiltering = true;
}
Ответ 2
Для .Net 4.5:
Существует новый интерфейс, который может помочь в достижении этой функции: ICollectionViewLiveShaping
.
От Ссылка MSDN:
Когда включена сортировка, группировка или фильтрация в реальном времени, CollectionView изменит положение данных в CollectionView, когда данные изменены. Например, предположим, что приложение использует DataGrid для перечисления акций на фондовом рынке, а акции сортируются по стоимость акций. Если в коллекции CollectionView включена активная сортировка, позиция запаса в DataGrid перемещается, когда значение запаса становится больше или меньше другой стоимости акций.
Дополнительная информация по интерфейсу выше:
http://www.jonathanantoine.com/2011/10/05/wpf-4-5-%E2%80%93-part-10-live-shaping/
Для .Net 4 и ниже:
Существует еще одна публикация по SO QA, которая может помочь вам:
Фильтр CollectionViewSource не обновляется при изменении источника