This is a migrated thread and some comments may be shown as answers.

PDF Export w ItemsControl

5 Answers 100 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Jonathan
Top achievements
Rank 1
Jonathan asked on 28 Jan 2012, 04:09 AM
I have a couple of InlineUIContainers inside the RichTextBox with ItemsControls in them.

When I export to PDF the items from the itemscontrols past the first page do not show up unless I scroll down and get them loaded into the visual tree. Printing works fine.

I have tried overriding the ItemsPanelTemplate with a StackPanel. I am using the latest internal SL5 bits. 

5 Answers, 1 is accepted

Sort by
0
Ivailo Karamanolev
Telerik team
answered on 01 Feb 2012, 10:35 AM
Hi,

Currently, exporting of InlineUIContainers that are not in the viewport is not supported in PDF. We have this on our to-do list, but it is not currently scheduled. What you can do is replace the InlineUIContainers with content of your choice: an image, text, or other content before exporting. In this way, when exported, the document will look correctly. You can also check the options that PdfExportSettings provide, described in this article: http://www.telerik.com/help/silverlight/radrichtextbox-features-import-export-settings.html#PdfFormatProvider_Settings

Let us know if you need additional assistance.

Greetings,
Ivailo Karamanolev
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Jonathan
Top achievements
Rank 1
answered on 02 Apr 2012, 05:49 PM
Thanks for getting back to me. I have been away from this for a while but I am back onto the problem.

I have ItemsControls inside of ItemsControls in the InlineUIContainers. 

If I scroll down to the bottom, they will generate/show up when I native print and when I export to PDF.
If I do not scroll down, they will only generate/show up on the front page when I native print and when I export to PDF.

How do you suggest I force the ItemsControls to generate?

Note: I already handle syncing the size change problem on the InlineUIContainer by manually tracking each item with the below code.

//Keep a list of size changed observables 
var uiElementSizeChangedObservables = new List<IObservable<InlineUIContainer>>();

//Add each uiElement
uiElementSizeChangedObservables.Add(Observable.FromEventPattern<SizeChangedEventHandler, SizeChangedEventArgs>(h => myUIElement.SizeChanged += h, h => myUIElement.SizeChanged -= h).Select(e => myInlineUIContainer));

//Buffer UIElements size changes for a second
//Then update the RichTextBox
uiElementSizeChangedObservables.Merge().Buffer(TimeSpan.FromSeconds(1)).ObserveOnDispatcher()
                    .Subscribe(containersToUpdate =>
                    {
                        foreach (var container in containersToUpdate)
                        {
                            var uiElement = container.UiElement;
                            var desiredHeight = uiElement.DesiredSize.Height;


                            if (desiredHeight > 0 && container.Height != desiredHeight)
                                container.Height = desiredHeight;
                        }


                        try
                        {
                            ManifestRichTextBox.UpdateEditorLayout();
                        }
                        catch {} //Ignore problems. An exception will occur when RichTextBox tries to print
                    });
0
Jonathan
Top achievements
Rank 1
answered on 02 Apr 2012, 05:56 PM
Another thing to note, the second time I print everything is generated even if I do not scroll down.
0
Ivailo Karamanolev
Telerik team
answered on 06 Apr 2012, 02:55 PM
Hi,

We are not aware of any workaround for the issue regarding generating the ItemsControl's items. This is not a very well supported scenario by Silverlight. I recommend that you replace the InlineUIContainers with images before exporting to PDF, as exporting the UI elements may cause various issues. If you decide to stick to UI elements, however, you can add the UI elements from code, skipping the use of ItemsControl.
Let us know if you need additional assistance.

All the best,
Ivailo Karamanolev
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Jonathan
Top achievements
Rank 1
answered on 13 Apr 2012, 11:38 PM
Converting it to images first works a lot better thanks.

For those interested I fixed this by adding the items to the visual tree before creating the images.

I open a RadBusyIndicator, add it to the content (which I put a stackpanel in), measure it, then create the image and add it to the RichTextBox.

/// <summary>
/// Takes a UI element converts it to an ImageInline
/// </summary>
/// <param name="uiElement">The uiElement to add to the RichTextBox</param>
/// <param name="customForceLayoutUpdate">An optional custom method to force the ui element's layout.</param>
private ImageInline ConvertToImageInline(UIElement uiElement, Action customForceLayoutUpdate = null)
{
    //To make sure the items controls render properly
    //add it to the BusyContent's StackPanel quickly then remove it
 
    //The BusyIndicator should be open when rendering manifests
    BusyContentStackPanel.Children.Add(uiElement);
 
    //Update the layout
    if (customForceLayoutUpdate != null)
        customForceLayoutUpdate();
    else
        BusyContentStackPanel.UpdateLayout();
 
    uiElement.Measure(new Size(double.MaxValue, double.MaxValue));
 
    var writableBitmap = new WriteableBitmap((int)uiElement.DesiredSize.Width, (int)uiElement.DesiredSize.Height);
    writableBitmap.Render(uiElement, null);
    writableBitmap.Invalidate();
 
    var radImage = new RadBitmap(writableBitmap);
 
    var stream = new MemoryStream();
    var provider = new PngFormatProvider();
    provider.Export(radImage, stream);
 
    //Remove it from the stackpanel so the user does not see it
    BusyContentStackPanel.Children.Remove(uiElement);
 
    return new ImageInline(stream);
}

I force update the itemscontrol's layout to render children itemscontrols.

//Force the element's itemscontrol to layout ChildControl items
element.UpdateLayout();
element.Measure(new Size(double.MaxValue, double.MaxValue));
 
//Force the element's ChildControl's ItemsControl to layout their items
foreach (var childControl in element.GetDescendants<ChildControl>())
{
    var childItem = childControl.DataContext as ChildItem;
 
    if (childItem == null)
      continue;
 
    //Force set the ItemsControl.ItemsSource because bindings will not happen in time
    childControl.SetItemsControlSource(childItem.Items);
    childControl.UpdateLayout();
    childControl.Measure(new Size(double.MaxValue, double.MaxValue));
}
 
element.Measure(new Size(double.MaxValue, double.MaxValue));
Tags
RichTextBox
Asked by
Jonathan
Top achievements
Rank 1
Answers by
Ivailo Karamanolev
Telerik team
Jonathan
Top achievements
Rank 1
Share this question
or