Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy are Silverlight ContentControls not garbage collected?
    primarykey
    data
    text
    <p>I've been investigating why some of my controls aren't being garbage collected and noticed it's easy to prevent simple controls that inherit from ContentControl from ever being destroyed. Here's an example:</p> <p>Here is my custom ContentControl:</p> <pre><code> public class MyCustomControl : ContentControl { public MyCustomControl() { Debug.WriteLine("Constructed"); } ~MyCustomControl() { Debug.WriteLine("Destroyed"); } } </code></pre> <p>Now if I put it on a page like so:</p> <pre><code>&lt;navigation:Page x:Class="SimpleTestBed.Views.CustomControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" xmlns:local="clr-namespace:SimpleTestBed" d:DesignWidth="640" d:DesignHeight="480" Title="CustomControl Page"&gt; &lt;Grid x:Name="LayoutRoot"&gt; &lt;StackPanel&gt; &lt;local:MyCustomControl&gt; &lt;TextBox Text="{Binding SomeProperty,Mode=TwoWay}"&gt;&lt;/TextBox&gt; &lt;/local:MyCustomControl&gt; &lt;/StackPanel&gt; &lt;/Grid&gt; </code></pre> <p> With the following code behind:</p> <pre><code> public partial class CustomControl : Page { public CustomControl() { InitializeComponent(); this.DataContext = new CustomControlViewModel(); this.Unloaded += new RoutedEventHandler(OnUnloaded); } void OnUnloaded(object sender, RoutedEventArgs e) { this.DataContext = null; } // Executes when the user navigates to this page. protected override void OnNavigatedTo(NavigationEventArgs e) { } } </code></pre> <p>Then the view model is:</p> <pre><code> public class CustomControlViewModel : INotifyPropertyChanged { #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { RaisePropertyChanged(propertyName); } private void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } #endregion private string _someProperty = "Initial Value"; public string SomeProperty { get { return _someProperty; } set { if (_someProperty != value) { string oldValue = _someProperty; _someProperty = value; OnPropertyChanged("SomeProperty"); OnSomePropertyChanged(oldValue, value); } } } protected virtual void OnSomePropertyChanged(string oldValue, string newValue) { } } </code></pre> <p>Now when I navigate away from this page and try garbage collecting with GC.Collect(), as long if I've made no changes to the text in the Textbox, the ContentControl and Page are destroyed as expected by the GC. But if I've edited some text and navigated away from the page and then tried to GC.Collect(), the ContentControl doesn't get garbage collected.</p> <p>Can anyone explain this behavior? </p> <p>Actually, you can force the GC to collect the control by 'flickering' the Template of the control when you unload:</p> <pre><code> void MyCustomControl_Unloaded(object sender, RoutedEventArgs e) { Debug.WriteLine("MyCustomControl Unloaded"); ControlTemplate oldTemplate = this.Template; this.Template = null; this.Template = oldTemplate; } </code></pre> <p>I presume this destroys the current visual tree losing references of the tree's first component to its parent (the custom control). It certainly forces the control to recall OnApplyTemplate when the control is reloaded. </p> <p>Is this the correct pattern for developing Silverlight controls without leaking? If so, it strikes me as a bit bizarre that the template isn't disposed automatically when the control unloads. </p> <p>A good account of this behavior would be much appreciated as it goes right to the heart of the life-cycle of Silverlight controls.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload