I am doing this in Caliburn Micro:
The view that host the Content Control:
<
Controls:TransitioningContentControl
Grid.Row
=
" Grid.Column="
x:Name
=
"ActiveItem"
/>
Test code in the view model - basically a timer that will assign TestSiteCollection[0] & TestSiteCollection[1] to ActiveItem repeatedly.
private void tmrMemTest_Tick(object sender, EventArgs e)
{
if (isAddLimit)
{
ActiveItem = TestSiteCollection[1];
isAddLimit = false;
}
else
{
ActiveItem = TestSiteCollection[0];
isAddLimit = true;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); // to see whether we have a leak or not.
}
}
One of the TestSiteCollection elements is the RadDocking & its view look likes this.
<
telerik:RadDocking
Grid.Row
=
" HasDocumentHost="
PanesSource
=
"{Binding TestPanelCollection, Mode=OneWay}"
>
<telerik:RadDocking.DockingPanesFactory>
<styles:CustomDockingPanesFactory/>
</telerik:RadDocking.DockingPanesFactory>
<telerik:RadSplitContainer InitialPosition="DockedLeft">
<telerik:RadPaneGroup x:Name="leftGroup" telerik:RadDocking.SerializationTag="leftGroup"/>
</telerik:RadSplitContainer>
<telerik:RadSplitContainer InitialPosition="DockedRight">
<telerik:RadPaneGroup x:Name="rightGroup" telerik:RadDocking.SerializationTag="rightGroup"/>
</telerik:RadSplitContainer>
<telerik:RadSplitContainer InitialPosition="DockedTop">
<telerik:RadPaneGroup x:Name="topGroup" telerik:RadDocking.SerializationTag="topGroup"/>
</telerik:RadSplitContainer>
<telerik:RadSplitContainer InitialPosition="DockedBottom">
<telerik:RadPaneGroup x:Name="bottomGroup" telerik:RadDocking.SerializationTag="bottomGroup"/>
</telerik:RadSplitContainer>
</telerik:RadDocking>
CustomDockingPanesFactory:
protected override RadPane CreatePaneForItem(object item)
{
var viewModel = item as TestPanelBase;
if (viewModel != null)
{
var pane = viewModel.IsDocument ? new RadDocumentPane() : new RadPane();
pane.DataContext = item;
pane.Header = viewModel.Header;
// When saving the layout, RadDocking control generates an xml schema for its elements and their position,
// size and other properties.
// We need to set a SerializationTag for each Pane. Otherwise, each time when loading,
// a new Pane will be generated and we will lose the DataContext, which is not desirable.
RadDocking.SetSerializationTag(pane, viewModel.Header);
if (viewModel.ContentType != null)
{
pane.Content = Activator.CreateInstance(viewModel.ContentType);
}
return pane;
}
return base.CreatePaneForItem(item);
}
protected override void RemovePane(RadPane pane)
{
// A problem could exist if you hold a reference to the old content or it was declared in XAML.
// There is one memory leak in the Docking control we are aware of -
// if you are removing the whole pane and it was the last one in the group,
// it is not destroyed before you add another pane in this group
pane.ClearValue(RadDocking.SerializationTagProperty);
// Removes the Pane from the RadDocking layout. By default clears the Header, Content, DataContext and call RemoveFromParent method.
base.RemovePane(pane);
}
What i have observed is that every time ActiveItem is assigned, CreatePaneForItem() is called. I am suspecting that is the cause of the memory leak.
What can i do to prevent this multiple call to CreatePaneForItem()?
p/s: i have cleaned up other misbehaving codes that have contributed to the memory leak & i am now stuck at this observation.