3

I have created a WPF viewmodel which have an ObservableCollection. The viewmodel is bound to usercontrol and the usercontrol is loaded in tabitem.

When I am removing the user control form Tabitem. The viewmodel is getting disposed but the ObservableCollection remains in memory ( I have not used the collection in the view) . I tested this using ANTS profiler.

Following is the object retention graph from the ANTS profiler.

enter image description here

The viewmodel code is as below:

namespace TestControl
{
    class UserControl4ViewModel : INotifyPropertyChanged
    {
        public UserControl4ViewModel()
        {
            fieldList = new ObservableCollection<Field>();
            fieldList.Add(new Field() { PersonName = "Test1" });
            fieldList.Add(new Field() { PersonName = "Test2" });
            fieldList.Add(new Field() { PersonName = "Test3" });
            fieldList.Add(new Field() { PersonName = "Test4" });
        }
        public ObservableCollection<Field> FieldList
        {
            get
            {
                return fieldList;
            }
            set
            {
                fieldList = value;
                OnPropertyChanged("FieldList");
            }
        }

        private ObservableCollection<Field> fieldList;

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }

        public void DisposeContent()
        {
            if (fieldList != null)
            {
                fieldList.Clear();
            }
            fieldList = null;
        }
    }

    public class Field 
    {
        public string PersonName { get; set; } 
    }
}

Field Class Code

public class Field 
        {
            public string PersonName { get; set; } 
        }

The user control code is

public partial class UserControl4 : UserControl
    {
        public UserControl4()
        {
            InitializeComponent();
        }

        private void UserControl_Unloaded(object sender, RoutedEventArgs e)
        {
            UserControl4ViewModel userControl4ViewModel =(UserControl4ViewModel) this.DataContext;
            userControl4ViewModel.DisposeContent();
        }

    }

The usercontrol XAML view code is

<UserControl x:Class="TestControl.UserControl4"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TestControl"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" Unloaded="UserControl_Unloaded">
    <UserControl.DataContext>
        <local:UserControl4ViewModel>
            </local:UserControl4ViewModel>
    </UserControl.DataContext>
    <Grid>

    </Grid>
</UserControl>

Please help me disposing Observable collection from the memory.

--Arun

Arun
  • 365
  • 1
  • 5
  • 15
  • 1
    I'd implement INotifyPropertyChanged on the Field class if I were you. – Philip Atanassov Feb 03 '15 at 13:47
  • Hi Philips, I tried doing that. But no luck. – Arun Feb 03 '15 at 14:27
  • please post Field class – eran otzap Feb 03 '15 at 14:28
  • I have added Field class in first snippet. here is for your reference ------------------------------------ public class Field { public string PersonName { get; set; } } – Arun Feb 03 '15 at 14:34
  • You could also try setting the FieldList property to null in the DisposeContent method in order to raise the PropertyChanged event for this. As it is currently (you setting the field to null instead of the property) the listeners in the UI would not know that you've set this property to null. – Philip Atanassov Feb 03 '15 at 14:49
  • does UserControl_Unloaded ever get called ? – eran otzap Feb 03 '15 at 14:53
  • @PhilipAtanassov Yes I have tried setting FielList property to null. its same issue. – Arun Feb 03 '15 at 14:57
  • @eranotzap Yes UserControl_Unloaded getting called. I did put the breakpoint and check this. – Arun Feb 03 '15 at 14:58
  • Are you using this FieldList collection events like collectionchanged in any other place? – Ayyappan Subramanian Feb 03 '15 at 15:35
  • @Ganesh no i am not using. I have pasted complete code – Arun Feb 03 '15 at 16:21
  • Garbage collector does its job in a non-deterministic way. That means, you cannot definetely say, when and on which thread it will dispose objects. Probably the `Field` objects are not being disposed because the garbage collector just "thinks" they don't need to right now. To which GC generation do all the `Field` objects belong? – dymanoid Feb 03 '15 at 19:30
  • @dymanoid I understood that garbage collection do this job non-deterministic way. But according to object retention graph, grabage collection thinks Field object is live. Write now Field object are available at generation 2 . – Arun Feb 04 '15 at 04:53

0 Answers0