Я определил свою привязку следующим образом:
<TreeView
ItemsSource="{Binding UsersView.View}"
ItemTemplate="{StaticResource MyDataTemplate}"
/>
CollectionViewSource определяется следующим образом:
private ObservableCollection<UserData> users;
public CollectionViewSource UsersView{get;set;}
UsersView=new CollectionViewSource{Source=users};
UsersView.SortDescriptions.Add(
new SortDescription("IsLoggedOn",ListSortDirection.Descending);
UsersView.SortDescriptions.Add(
new SortDescription("Username",ListSortDirection.Ascending);
Пока все хорошо, все работает, как и ожидалось: представление показывает сначала пользователей, которые вошли в алфавитном порядке, а затем тех, кто не является.
Однако свойство IsLoggedIn в UserData обновляется каждые несколько секунд потоком фонового работника, а затем код вызывает:
UsersView.View.Refresh();
в потоке пользовательского интерфейса.
Опять же, это работает как ожидалось: пользователи, которые входят в систему, перемещаются из нижней части представления в верхнюю и наоборот. Однако: Каждый раз, когда я вызываю метод Refresh в представлении, приложение накапливает 3,5 МБ дополнительной памяти, которая освобождается только после завершения работы приложения (или после исключения OutOfMemoryException ...)
Я провел некоторое исследование, и ниже приведен список исправлений, которые НЕ работали:
- Класс UserData реализует INotifyPropertyChanged
- Изменение базовой коллекции пользователей не имеет никакого значения: любая IENumerable
<UserData
> как источник для CollectionViewSource вызывает проблему.
-Изменение ColletionViewSource в List <UserData
> (и обновление привязки) или наследование от ObservableCollection для получения доступа к базовой коллекции Items для сортировки на месте не работает.
У меня нет идей! Помощь
EDIT:
Я нашел это:
Resource MyDataTemplate содержит метку, которая привязана к объекту UserData для отображения одного из его свойств, объекты UserData передаются из TreeS в ItemsSource. Метка имеет ContextMenu, определенное таким образом:
<ContextMenu Background="Transparent" Width="325" Opacity=".8" HasDropShadow="True">
<PrivateMessengerUI:MyUserData IsReadOnly="True" >
<PrivateMessengerUI:MyUserData.DataContext>
<Binding Path="."/>
</PrivateMessengerUI:MyUserData.DataContext>
</PrivateMessengerUI:MyUserData>
</ContextMenu>
Объект MyUserData - это UserControl, который показывает все свойства объекта UserData. Таким образом, пользователь сначала видит только один фрагмент данных пользователя, а при щелчке правой кнопкой мыши видит их все.
Когда я удаляю MyCserData UserControl из DataTemplate, утечка памяти исчезает! Как я все еще могу реализовать поведение, как указано выше?