PDF Export w ItemsControl

6 posts, 0 answers
  1. Jonathan
    Jonathan avatar
    37 posts
    Member since:
    Jul 2012

    Posted 27 Jan 2012 Link to this post

    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. 

  2. Ivailo Karamanolev
    Admin
    Ivailo Karamanolev avatar
    276 posts

    Posted 01 Feb 2012 Link to this post

    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 >>

  3. DevCraft banner
  4. Jonathan
    Jonathan avatar
    37 posts
    Member since:
    Jul 2012

    Posted 02 Apr 2012 Link to this post

    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
                        });
  5. Jonathan
    Jonathan avatar
    37 posts
    Member since:
    Jul 2012

    Posted 02 Apr 2012 Link to this post

    Another thing to note, the second time I print everything is generated even if I do not scroll down.
  6. Ivailo Karamanolev
    Admin
    Ivailo Karamanolev avatar
    276 posts

    Posted 06 Apr 2012 Link to this post

    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 >>

  7. Jonathan
    Jonathan avatar
    37 posts
    Member since:
    Jul 2012

    Posted 13 Apr 2012 Link to this post

    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));
Back to Top
DevCraft banner