Can't add InlineUIContainer to header section of RadRichTextBox

6 posts, 2 answers
  1. ①Dr Mostafa
    ①Dr Mostafa avatar
    14 posts
    Member since:
    Oct 2015

    Posted 23 Jul Link to this post

    Hi Every Body…

    I use RadRichTextBox control, and my requirement is to add border to every page in the document, like that shown in the attached image.

    As RadRichTextBox control doesn't support adding shapes, I tried using DecorationUILayerBase, but unfortunately I couldn't use it with the headers (to achieve my requirement).

    So I tried another technique utilizing InlineUiContaineers, where I created the required structure (including the require border) and added them to a Grid control, then adding that Grid to an instance of InlineUIContainer class, and adding that instance to the header section of an instance of RadDocument class, and finally setting that instance to the Document property of my RadRichTextBox control.

    This solution worked for the header of the first page only, but as the user continues writing and reaching end of this first page and new page is added the following error is thrown:
    "Specified element is already the logical child of another element. Disconnect it first."

    My code snippet is as the following:

    Me.radRichTextBox.Document = CreateDocumentWithCustomHeader()
    Public Function CreateDocumentWithCustomHeader() As RadDocument
                Dim doc As New RadDocument()
                doc.LayoutMode = DocumentLayoutMode.Paged

                Dim headerDoc As New RadDocument()
                Dim hSection As New Section()
                headerDoc.Sections.Add(hSection)
                headerDoc.SectionDefaultPageMargin = New Telerik.Windows.Documents.Layout.Padding(5, 5, 5, 5)

                Dim hparagraph As New Paragraph()
                hSection.Blocks.Add(hparagraph)

                Dim grid As New Grid
                Dim column1 As New ColumnDefinitionWith {.Width = NewGridLength(150)}
                Dim column2 As New ColumnDefinitionWith {.Width = NewGridLength(0, GridUnitType.Star)}
                Dim column3 As New ColumnDefinitionWith {.Width = NewGridLength(150)}
                grid.ColumnDefinitions.Add(column1)
                grid.ColumnDefinitions.Add(column2)
                grid.ColumnDefinitions.Add(column3)
                Dim MinistryImage As New Image
                MinistryImage.Source = BitmapManager.CreateBitmapImage("pack://application:,,,/Images/ Logo1.png", 150)
                Dim LogoImage As New Image
                LogoImage.Source = BitmapManager.CreateBitmapImage("pack://application:,,,/Images/Logo2.png", 150)
                grid.SetColumn(LogoImage, 0)
                grid.SetRow(LogoImage, 0)
                grid.SetColumn(MinistryImage, 2)
                grid.SetRow(MinistryImage, 0)
                grid.Children.Add(LogoImage)
                grid.Children.Add(MinistryImage)
                Dim border As New Controls.BorderWith {.BorderThickness = New Thickness(4), .CornerRadius = New CornerRadius(5), .BorderBrush = New SolidColorBrush(Colors.Black)}
                grid.SetColumn(border, 0)
                grid.SetRow(border, 0)
                grid.SetColumnSpan(border, 3)
                grid.Children.Add(border)
                border.HorizontalAlignment = Windows.HorizontalAlignment.Stretch
                border.VerticalAlignment = Windows.VerticalAlignment.Stretch
                border.Margin = New Thickness(5, 5, 5, -500)

                grid.HorizontalAlignment = Windows.HorizontalAlignment.Stretch
                grid.VerticalAlignment = Windows.VerticalAlignment.Stretch

                Dim container As New InlineUIContainer()
                container.UiElement = grid
                container.Height = 150
                container.Width = 700
                hparagraph.Inlines.Add(container)

                Dim header As New Header()
                header.Body = headerDoc

                Dim section As New Section()
                section.Headers.Default = header
                doc.Sections.Add(section)
                doc.SectionDefaultPageMargin = New Telerik.Windows.Documents.Layout.Padding(10, 10, 10, 10)

                Return doc
            End Function

  2. ①Dr Mostafa
    ①Dr Mostafa avatar
    14 posts
    Member since:
    Oct 2015

    Posted 23 Jul Link to this post

    My question is what is the best way I can use to add a border to header of every page of the document
  3. Answer
    Mihail
    Admin
    Mihail avatar
    223 posts

    Posted 26 Jul Link to this post

    Hello Mostafa,

    The problem you encounter is expected. Let me explain it in details.
    The header of the second page is creating a copy of the first header which contains InlineUIContainer. However, the InlineUIContainer is not copyable. The reason for this is because the InlineUIContainer actually uses the WPF class UIElement which is not copyable.
    You could implement a custom InlineUIContainer and create the copy functionality by yourself. In your scenario for a grid and its children. Here is a very simple example of how a button with content could be copied:
    public class CopyableInlineUIContainer : InlineUIContainer
    {
        internal CopyableInlineUIContainer()
        {
     
        }
     
        public CopyableInlineUIContainer(UIElement uiElement, Size size) : base(uiElement, size)
        {
     
        }
     
        public override bool IsCopyable
        {
            get
            {
                return true;
            }
        }
     
        protected override DocumentElement CreateNewElementInstance()
        {
            return new CopyableInlineUIContainer();
        }
     
        protected override void CopyPropertiesFromOverride(DocumentElement fromElement)
        {
            CopyableInlineUIContainer fromUIContainer = (CopyableInlineUIContainer)fromElement;
            this.Width = fromUIContainer.Width;
            this.Height = fromUIContainer.Height;
     
            if (fromUIContainer.UiElement is Button)
            {
                var fromButton = (Button)fromUIContainer.UiElement;
     
                var button = new Button();
                button.Content = fromButton.Content;
     
                this.UiElement = button;
            }
            else
            {
                throw new NotImplementedException("The UiElement is not copyable.");
            }
        }
    }

    Regarding your question for the border in the header of the page, I am afraid that this scenario is not supported out of the box. You could add a table with a border to the header and add your content in the table. Please have in mind that the rounded edges of the border will not be achieved.
    Of course, you could explore the option with the InlineUIContainer further for achieving this scenario.

    I hope this information is helpful.

    Regards,
    Mihail
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  4. ①Dr Mostafa
    ①Dr Mostafa avatar
    14 posts
    Member since:
    Oct 2015

    Posted 29 Jul in reply to Mihail Link to this post

    Thank you very much Mihail for your kind support and I apologize for the delay of response. I will try your solution and will inform you soon with the result.
  5. ①Dr Mostafa
    ①Dr Mostafa avatar
    14 posts
    Member since:
    Oct 2015

    Posted 29 Jul Link to this post

    Thank you very very much again Mihail. Your solution is the exact solution I want. It took me a lot of time figure it out...

    One last thing, I would like to know; where I realized that there is deficiency in the documentation regarding classes and methods provided by telerik. I'm telling that because I already tried inheriting from "InlineUIContainer" class to solve my problem like you did, but unfortunately I didn't find any information regarding how to use "CopyPropertiesFromOverride" method provided by this class. The only information that I found (after searching the web) is that: I can override this method to apply my custom implementation, but how; i didn't find any resources tilling how to do this.

    So the question is: Is there a rich resources tilling every detail about every method provided by telerik, like that documentation provided by Microsoft?.

    I hope you provide such a requirement, because I think that your company (i.e. telerik) is a great company that will invade the whole world soon and such documentation (as I described) will be very important.

    Thank you very much for time...

  6. Answer
    Tanya
    Admin
    Tanya avatar
    575 posts

    Posted 02 Aug Link to this post

    Hi Mostafa,

    Thank you for the feedback, it is much appreciated.

    Indeed, there are no resources related to the customization of InlineUIContainer objects. We have already logged a task to describe such a scenario and will update the information as soon as we get a chance to do so.

    All the members in the UI for WPF suite are listed in the API Reference part of the documentation. The documentation for each control contains more detailed explanations on the different functionalities and customization options.

    Regards,
    Tanya
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Back to Top