Memory Leak when using BindingList<>

Memory Leak when using BindingList<>

Ok, I’ve narrowed down where / when the memory leak is that I had found. I do not know if it is something that I am doing or a problem with the control itself. If it is something in what I am doing, can someone please let me know how to fix the problem on my end.

The problem is when using a BindingList<> to be able to support the control’s functions since creating new items using InsertionRow does not currently work with ObservableCollection<>. I’ve copied a sample of some offending code below that replicates the problem. The memory from the collection is never freed in Garbage Collection, even though it shouldn’t be referenced any more by the DataGridControl.

Any help on this would be greatly appreciated.

If it helps anyone to narrow down the problem, the errors that I am showing in the console output are:

System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’Xceed.Wpf.DataGrid.DataGridControl’, AncestorLevel=’1”. BindingExpression:Path=ViewBindingContext.HorizontalGridLineThickness; DataItem=null; target element is ‘ColumnManagerRow’ (Name=”); target property is ‘BorderThickness’ (type ‘Thickness’)
System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’Xceed.Wpf.DataGrid.DataGridControl’, AncestorLevel=’1”. BindingExpression:Path=ViewBindingContext.HorizontalGridLineBrush; DataItem=null; target element is ‘ColumnManagerRow’ (Name=”); target property is ‘BorderBrush’ (type ‘Brush’)
System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’Xceed.Wpf.DataGrid.DataGridControl’, AncestorLevel=’1”. BindingExpression:Path=ViewBindingContext.HorizontalGridLineBrush; DataItem=null; target element is ‘VirtualizingStackPanel’ (Name=”); target property is ‘ContentBorderBrush’ (type ‘Brush’)
System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’Xceed.Wpf.DataGrid.DataGridControl’, AncestorLevel=’1”. BindingExpression:Path=ViewBindingContext.HorizontalGridLineThickness; DataItem=null; target element is ‘VirtualizingStackPanel’ (Name=”); target property is ‘ContentBorderThickness’ (type ‘Thickness’)

The sample code to replicate it is as follows:

<DockPanel x:Name=”uxLayoutRoot”>
<Button Click=”GarbageCollect” DockPanel.Dock=”Top”>Garbage Collect</Button>
<Button Click=”LoadNewObject” DockPanel.Dock=”Top”>Load New Object</Button>
<xcdg:DataGridControl x:Name=”uxGrid” ItemsSource=”{Binding Path=Collection}”>
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName=”Data” />
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
</DockPanel>

public partial class Window1 : System.Windows.Window
{
private MyRootClass _root = new MyRootClass();

public Window1()
{
InitializeComponent();

Binding binding = new Binding();
binding.Source = _root;

uxLayoutRoot.SetBinding(DockPanel.DataContextProperty, binding);
}

private void GarbageCollect(object sender, RoutedEventArgs e)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}

private void LoadNewObject(object sender, RoutedEventArgs e)
{
_root.LoadNewCollection();
}
}

public class MyRootClass : INotifyPropertyChanged
{
private BindingList<MySubData> _collection;

public event PropertyChangedEventHandler PropertyChanged;

public MyRootClass()
{
LoadNewCollection();
}

public BindingList<MySubData> Collection
{
get
{
return _collection;
}
set
{
_collection = value;

if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(“Collection”));
}
}
}

public void LoadNewCollection()
{
BindingList<MySubData> obj = new BindingList<MySubData>();

for (int i = 0; i < 100000; i++)
{
obj.Add(new MySubData(“sample string of data… one of many…”));
}

Collection = obj;
}

}

public class MySubData : INotifyPropertyChanged
{
private string _data;

public event PropertyChangedEventHandler PropertyChanged;

public MySubData(string data)
{
_data = data;
}

public string Data
{
get
{
return _data;
}
set
{
_data = value;

if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(“Data”));
}
}
}
}