A memory leak in RadPdfViewer when the control gets removed from the visual tree.
To work this around, use the reflection API to access the leaking VisualTarget objects and call their Dispose method manually.
var pdfViewer = hostBorder.Child as RadPdfViewer;
if (pdfViewer != null)
{
var canvas = viewer.ChildrenOfType<Canvas>().FirstOrDefault(x => x.GetType().Name.Contains("ContentElementsCanvas"));
var visualTargetsDictionaryField = canvas.GetType().GetField("pageNumberToVisualTarget", BindingFlags.NonPublic | BindingFlags.Instance);
var visualTargetsDictionary = (Dictionary<int, List<VisualTarget>>)visualTargetsDictionaryField.GetValue(canvas);
foreach (KeyValuePair<int, List<VisualTarget>> target in visualTargetsDictionary)
{
for (int i = 0; i < target.Value.Count; i++)
{
VisualTarget item = target.Value[i];
item.RootVisual = null;
item.Dispose();
}
}
}
hostBorder.Child = null;
hostBorder.Child = new RadPdfViewer() { Document = newDocument };
The attached image shows the issue.
A memory leak occurs in the RadTreeView control used for the table of contents in the RadPdfViewerNavigationPane, when changing the DocumentSource of RadPdfViewer at runtime.
To work this around, you can get the RadTreeView used by RadPdfViewerNavigationPane and manually clear its internal item storage before assigning the new DocumentSource.
private void ReloadDocument()
{
var navigationPane = this.pdfViewerNavigationPane;
var navigationPaneTreeView = navigationPane.FindChildByType<RadTreeView>();
if (navigationPaneTreeView != null)
{
object itemStorage = typeof(RadTreeView)
.GetProperty("ItemStorage", BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(navigationPaneTreeView);
MethodInfo itemStorageClearMethod = itemStorage.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.NonPublic);
itemStorageClearMethod.Invoke(itemStorage, null);
}
this.DocumentSource = theNewDocumentSource;
}