【发布时间】:2012-10-16 16:28:51
【问题描述】:
我正在构建一个 WPF 应用程序,该应用程序使用 LINQ to SQL 连接到 SQL Server 数据库。
应用程序的主窗口包含一个ListView,其中包含一系列详细视图。
ItemSource 的 ItemSource 绑定到作为根视图模型上的属性公开的详细视图模型对象的集合。
每个详细视图模型对象都由几个ICommand 属性以及一个公开详细模型对象的属性组成,后者又公开了 UI 中显示的各种数据字段。
使用 ANTS 内存分析器的分析表明,泄漏的对象是包含在详细模型对象中的对象,以及它们所绑定的一些 UI 类。 以前刷新的这些对象的实例不会被垃圾收集。
ANTS 有一个工具,允许用户跟踪引用链,以确定保留不需要的内存的原因。当我使用它时,我发现所有出现的链都有一个ICommand。因此,我删除了有问题的ICommand,并发现
内存泄漏消失了。
不幸的是,我需要ICommand 来实现一些重要的功能。真正让我困惑的是它首先是如何引用细节模型对象的——它们是细节视图模型对象中两个完全独立的实例变量。
这里是详细视图模型对象的构造函数(对 RootViewModel 的引用用于在连接到 ICommands 的某些方法中的回调。我最初怀疑这可能导致循环引用链,可能是问题的原因,但删除它似乎没有任何效果。)
public CarDataViewModel(CarData carDataItem, RootViewModel parentViewModel)
{
_parentViewModel = parentViewModel;
CarDataModel = carDataItem;
CompetingCheckboxStatus = CarDataModel.CurrentCar.Competing;
AcknowledgeAlarm = new ParameterlessCommand(AcknowledgeAlarmClicked);
Acknowledge = new ParameterlessCommand(AcknowledgeClicked);
ShowReport = new ParameterlessCommand(ShowReportClicked);
Cancel = new ParameterlessCommand(CancelClicked);
}
这是设置绑定的 xaml - AcknowledgeAlarm 是 ICommand,CarDataModel 是详细模型对象:
<ListView x:Name="itemGridView"Grid.Row="1"ScrollViewer.HorizontalScrollBarVisibility="Disabled" ItemsSource="{Binding CarDataViewModels}" IsSynchronizedWithCurrentItem="True" Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
</DataTemplate.Resources>
<Button Command="{Binding AcknowledgeAlarm}">
<Border DataContext="{Binding CarDataModel}" BorderBrush="{StaticResource GrayFadeBrush}" Background="White" BorderThickness="5">
<Grid> . . .
【问题讨论】:
-
我怀疑这可能与 ParameterlessCommand 中的 CanExecuteChanged 事件有关。你能说明它是如何实现的吗?
-
它是
public event EventHandler CanExecuteChanged;,protected virtual void OnCanExecuteChanged(EventArgs args) { if (CanExecuteChanged != null) { CanExecuteChanged(this, args); } }- 抱歉格式化,似乎无法添加返回