【发布时间】:2011-01-26 18:45:31
【问题描述】:
我已经这样定义了我的绑定:
<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);
到目前为止,一切顺利,按预期工作:视图首先显示按字母顺序登录的用户,然后是未登录的用户。
但是,UserData 的 IsLoggedIn 属性每隔几秒由后台工作线程更新一次,然后代码调用:
UsersView.View.Refresh();
在 UI 线程上。
这再次按预期工作:登录的用户从视图的底部移动到顶部,反之亦然。但是:每次我在视图上调用 Refresh 方法时,应用程序都会囤积 3.5MB 的额外内存,这些内存仅在应用程序关闭后(或 OutOfMemoryException...)才会释放
我做了一些研究,以下是无效的修复列表:
- UserData 类实现 INotifyPropertyChanged
- 更改底层用户集合根本没有任何区别:任何 IENumerable
<UserData> 作为 CollectionViewSource 的源都会导致问题。
- 将 ColletionViewSource 更改为 List<UserData>(并刷新绑定)或从 ObservableCollection 继承以访问底层 Items 集合以对其进行就地排序不起作用。
我没有想法!帮忙?
编辑: 我找到了: Resource MyDataTemplate 包含一个绑定到 UserData 对象以显示其属性之一的 Label,UserData 对象由 TreeView 的 ItemsSource 传递。 Label 有一个这样定义的 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 对象是一个显示 UserData 对象所有属性的 UserControl。这样用户首先只能看到一个用户的一条数据,然后右键点击就可以看到全部。
当我从 DataTemplate 中删除 MyUserData UserControl 时,内存泄漏消失了!我怎样才能仍然实现上面指定的行为?
【问题讨论】:
-
您可以发布您的编辑作为答案并接受。
-
您还在寻找内存泄漏的原因吗?你能发送重现泄漏的“POC”吗?
-
@UserFriendly:我还是想知道,是的。现在我只有在得到 OutOfMemoryExceptions 后才发现它。我想先预防一下 ;-)(NOOB 警报:)什么是 POC?
-
:) 好的,POC 是概念证明。证明任何想法的东西。在您的情况下,POC 是一个简单的应用程序,内部存在内存泄漏:)
标签: c# .net wpf data-binding memory-leaks