我有一种奇怪的行为,我认为这与Binding有关。基本上,我怀疑我的控件在我的ViewModel上的绑定创建了一个从PropertyChanged事件到控件的强引用。因此,ViewModel始终保持对控件的引用。因此,即使我完成了控件,它们也始终保存在内存中。这将保留到我销毁我的ViewModel,但在我的情况下,我有一个ViewModel用于所有内容。有没有办法解开绑定所创建的事件?
以下是对我的问题的更详细的解释,以及引导我达到上述信念的那个:
我有一个ViewModel:
public ViewModel()
{
InitializeCommands();
}
public ICommand OpenPropertiesCommand { get; set; }
private void InitializeCommands()
{
OpenPropertiesCommand = new DelegateCommand((o) =>
{
OpenProperties(o as ContentControl);
});
}
private void OpenProperties(ContentControl propertiesWindowOwner)
{
JobProperties jp = new JobProperties(this);
jp.WindowStartupLocation = Telerik.Windows.Controls.WindowStartupLocation.CenterOwner;
jp.Owner = propertiesWindowOwner;
jp.ShowDialog();
}
private Job selectedJob;
public Job SelectedJob
{
get
{
return selectedJob;
}
set
{
selectedJob = value;
RaisePropertyChanged("SelectedJob");
}
}
此ViewModel由我的Main控件使用。在这个控件上,我有一个GridView,其中每一行都是一个“Job”。您可以编辑Job的属性,然后打开RadWindow Control,可以编辑每个作业的属性。
我的PropertyEdit Control是一个RadWindow,它使用与DataContext相同的ViewModel。所有这些组件都绑定在SelectedJob.something上,其中某些东西是Job的属性。
如果我打开Job#1属性。创建PropertyEdit控件并建立绑定。对于每个绑定,我的属性SelectedJob.something将被访问一次。如果我关闭PropertyEdit控件并再次打开Job#1属性。再创建一个PropertyEdit控件并建立绑定。现在,如果我关闭这个,并选择另一个Job,则在selectedJob上调用PropertyChanged事件,并为每个绑定调用两次绑定。实际上,第一个PropertyEdit控件绑定被激活,第二个PropertyEdit绑定也被激活。现在,如果我打开Job#1属性100次,当我选择Job#2时,将为每个属性查询绑定100次。因此,我怀疑内存泄漏,其中绑定将我的PropertyEdit控件保留在内存中,因为它们包含对所有这些的引用。在我销毁我的ViewModel之前,这些引用将被保留,但就我而言,它是我的主应用程序的ViewModel,永远不会被销毁。我怎样才能防止这种情况发生?有没有办法可以手动取消注册绑定的事件?
谢谢。
答案 0 :(得分:0)
我已经解决了这个问题。问题不在于绑定,但似乎Window的Owner属性以某种方式阻止窗口被垃圾收集。
通过评论这一行:
jp.Owner = propertiesWindowOwner;
我解决了这个问题。我不知道为什么会这样。我怀疑设置窗口的所有者有副作用,将窗口设置为propertiesWindowOwner的子窗口。因此,在我销毁propertiesWindowOwner之前,它会保留对我的窗口的引用,即使在关闭它之后。
我对于为什么会发生这种情况感到有点困惑,以及在执行此操作时我要求不要泄漏内存。如果有人知道,请对此发表评论。