I am having a strange behavior that I believe is related to the Binding. Basically, I suspect that the binding of my controls on my ViewModel creates a strong reference from the PropertyChanged event to the control. So the ViewModel always keeps a reference to the controls. Therefore, even though I am done with the controls, they are always kept in memory. This will remain until I destroy my ViewModel, but in my case, I have one ViewModel for everything. Is there a way I can unhook the events created by the bindings?
Here is a more detailed explanation of my issue, and the one that lead me to the above belief:
I have a 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");
}
}
This ViewModel is used by my Main control. On this control, I have a GridView where each Row is a “Job”. You can edit Job’s properties, which will in turn open a RadWindow Control that lets you edit each job’s properties.
My PropertyEdit Control is a RadWindow that uses the same ViewModel as it’s DataContext. All of it’s components bind on SelectedJob.something where something is a property of Job.
If I open Job #1 properties. A PropertyEdit control is created and binding is established. My properties SelectedJob.something are getting accessed once for each binding as should be. If I close the PropertyEdit control and open Job #1 properties again. One more PropertyEdit control is created and binding is established. Now if I close this one, and select another Job, a PropertyChanged event is called on selectedJob and my bindings are called twice for each binding. In effect, the first PropertyEdit control binding are activated, and the second PropertyEdit bindings are also activated. Now if I opened Job #1 properties 100 times, when I select Job #2, bindings will be queried 100 times for each one of them. Therefore, I suspect a memory leak, where the bindings are keeping my PropertyEdit control in memory, because they hold a reference to all of them. Until I destroy my ViewModel, those references will be kept, but in my case, it is my Main app’s ViewModel, and will never be destroyed. How can I prevent this from happening? Is there a way I can unregister the binding’s events manually?
Thank You.
I have solved this issue. The problem was not with the binding, but it seems that the Owner property of the Window somehow stops the window from being garbage collected.
By commenting out this line:
I solved the issue. I am not sure why this is. I suspect that setting the owner of the window has the side effect of setting the window as the child of the propertiesWindowOwner. Therefore, until I destroy the propertiesWindowOwner, it would keep a reference to my window, even after closing it.
I am a bit confused as to why this happens, and what I am required to do not to leak memory when doing this. If anyone knows, please comment on this.