Viewable portion of a RadDocument

12 posts, 0 answers
  1. Peter
    Peter avatar
    13 posts
    Member since:
    Feb 2014

    Posted 22 Jul 2014 Link to this post

    Hello,

    I am using the RadRichTextBox in a custom reporting solution in my application.  I have a situation where the user has entered comments in rtf format in our application and I need to show these in a report.  However, the comments may exceed the space on one page, so I need to detect the portion of the document that is visible within the bounds of the control and then split the document up over two or more pages, each with its own RadRichTextBox control.

    When I check the CaretPosition at the end of the document the Y value on the Location property is less than the height of my control, but the text exceeds the bounds of the control when viewed.

    Here is the code I am using:

    DocumentPosition caretPos = null;
    DocumentPosition endOfDocument = null;
     
    var rtfText = myRtfText;
    if (rtfText != null)
    {
        var provider = new RtfFormatProvider();
        var radDocument = provider.Import(rtfText);
        radDocument.SectionDefaultPageSize = new Size(maximumSize.Width, maximumSize.Height);
        var radRichTextBox = new RadRichTextBox{Document = radDocument};
     
        DocumentPosition tempPos = radRichTextBox.Document.CaretPosition;
        tempPos.MoveToLastPositionInDocument();
        endOfDocument = new DocumentPosition(tempPos);
     
        caretPos = radRichTextBox.Document.CaretPosition;
        caretPos.MoveToFirstPositionInDocument();
     
        if(caretPos != endOfDocument)
        {
            var start = new DocumentPosition(radRichTextBox.Document.CaretPosition);
            while (caretPos.Location.Y - start.Location.Y < maximumSize.Height)
            {
                if (!radRichTextBox.Document.CaretPosition.MoveToCurrentLineEnd())
                    break;
                if (!radRichTextBox.Document.CaretPosition.MoveNext())
                    break;
            }
            if (caretPos.Location.Y - start.Location.Y > maximumSize.Height)
            {
                // Back up so the content fits within the range
                radRichTextBox.Document.CaretPosition.MoveToLastPositionInPreviousParagraph();
            }
     
            var docSelection = new DocumentSelection(radRichTextBox.Document);
            docSelection.SetSelectionStart(start);
            docSelection.AddSelectionEnd(caretPos);
     
            var docFragment = new DocumentFragment(docSelection);
            var newDoc = new RadDocument();
            var editor = new RadDocumentEditor(newDoc);
            editor.InsertFragment(docFragment);
            var rtfSegment = provider.Export(newDoc);
         }
      }

    Also, attached is an image of the report with the control on it, clearly showing that there is text beyond the bottom of the control.

    Any insight you could offer would be appreciated.

    Thanks,

    Peter
  2. Petya
    Admin
    Petya avatar
    975 posts

    Posted 25 Jul 2014 Link to this post

    Hi Peter,

    I'm a bit confused by your scenario. RadRichTextBox has a Paged layout mode that would automatically split your document into pages, so I am not sure why you need to place content in several RadRichTextBox instances.

    As to your question, if the control visible in the attached image is a RadRichTextBox, it seems to be in Flow layout mode. Please note that if the RTF document you are importing (myRtfText) is in Paged mode, the measure of the control and all locations of the document positions after that will be determined in this mode, which may result in the behavior you are seeing.

    Also, the SectionDefaultSize property of a RadDocument determines the size of each section, but the control can show several sections at a time, so you should set the dimensions to the RadRichTextBox instance you've created instead. 

    Additionally, there is a pretty straightforward way to determine what the last document position in the active viewport is. Please check the below snippet.
    DocumentPosition pos = this.radRichTextBox.ActiveEditorPresenter.GetDocumentPositionFromViewPoint(new Point(this.radRichTextBox.ActiveEditorPresenter.ViewportWidth - (this.radRichTextBox.Padding.Left + this.radRichTextBox.Padding.Right), this.radRichTextBox.ActiveEditorPresenter.ViewportHeight - (this.radRichTextBox.Padding.Top + this.radRichTextBox.Padding.Bottom)));

    I hope this is helpful. Let me know if I can assist you with anything else.

    Regards,
    Petya
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  3. UI for WPF is Visual Studio 2017 Ready
  4. Peter
    Peter avatar
    13 posts
    Member since:
    Feb 2014

    Posted 25 Jul 2014 in reply to Petya Link to this post

    Thanks Petya.  To explain further, I have a custom reporting implementation where the user can create reports with predefined components, one of which is a text component which will display rich text comments that they have entered elsewhere in the application and stored in a record.

    In some cases, the user may have created a small text component (they set the size) that isn't large enough to display all of the rtf data that has been entered.  In this case, I need to determine how much will be displayed in the first component and then dynamically create extra report pages with another text box to display the rest of the comments.

    This is why I need to break the rtf up, or at least force the text control to show only the portion that I need for that particular page.
    I thought that I could use the RadDocument, RadEditor and/or RadRichTextBox classes in my code to help me break up the rtf, while maintaining all of the formatting.

    Creating additional report pages with their own RadRichTextBox controls is not the problem, it's splitting up the document to display in the multiple controls.  If I could even for the richtextbox to scroll to the correct position in the document, that would accomplish the same goal.

    Any help would be appreciated.

    Thanks,

    Peter
  5. Petya
    Admin
    Petya avatar
    975 posts

    Posted 30 Jul 2014 Link to this post

    Hi Peter,

    I'm afraid I still don't quite understand what you are trying to achieve and this seems as a rather unusual scenario for RadRichTextBox. Additionally, like I mentioned in the other thread you started on the topic, if you split a document in this manner you could experience loss of some document data and styling.

    Also, as far as I can tell from the picture in your first post, you are exporting the content of RadRichTextBox to PDF by taking a picture. However, the control has its own exporting functionality that would allow you to produce a paged PDF with all content in it. 

    As to scrolling to a portion of the document, this is a feasible scenario for RadRichTextBox. You can use the ScrollToVerticalOffset() and determine the needed offset based on some custom requirements or a document position. For example, say the RadRichTextBox in your application is in Paged layout mode and you want to scroll to the second page. Here is how you can accomplish this:
    DocumentPosition pos = new DocumentPosition(this.radRichTextBox.Document);
    pos.MoveToFirstPositionOnNextPage();
     
    double offset = pos.Location.Y;
    this.radRichTextBox.ScrollToVerticalOffset(offset);

    Regards,
    Petya
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  6. Peter
    Peter avatar
    13 posts
    Member since:
    Feb 2014

    Posted 04 Aug 2014 in reply to Petya Link to this post

    Hi Petya,

    Thanks for the suggested code, that got me part of the way.

    More info on my scenario: we are using RadDiagram as the basis for a custom reporting solution where the user is able to create their own report by dragging components onto the RadDiagram (similar to dragging controls to a new form in Visual Studio).  One of these components contains a RadRichTextBox to display the user's comments from data records.

    I have attached a screenshot of our report designer that includes a comment component/RadRichTextBox control.

    My problem is if the user creates a comment component that is too small to show all of their rtf text, we need to dynamically add one or more new pages (not document pages, but RadDiagrams) to our report to display the remainder of the rtf text from the record.  Thus, I have to determine how much of the rtf text was able to be shown in the previous comment component and continue from there in the next instance, without losing any formatting.

    I have successfully done this with a numbered list, but then my logic doesn't work when the rtf is standard paragraphs.  I need a way to determine exactly where in the RadDocument the previous control left off and pick up from there.

    Hopefully, this clarifies my situation a bit more.  If you need more info from me, let me know.

    Thanks,

    Peter

  7. Petya
    Admin
    Petya avatar
    975 posts

    Posted 07 Aug 2014 Link to this post

    Hello Peter,

    Thank you for the clarifications.

    I'm afraid the scenario you have in mind is a bit off the scope of RadRichTextBox, especially if you are planning on making the controls editable. Additionally, you should be aware that RadRichTextBox is a somewhat heavy component due to the rich set of features it exposes and placing several controls in a view could cause performance diminishment in your project.

    If you still choose to utilize the component, I would recommend not splitting the document to several smaller documents, as that would make its preservation difficult. Instead, import your data to separate RadDocument instances, assign them to the RadRichTextBoxes in the view and scroll to the desired portions of the document. The next code snippet demonstrates how you can obtain a document position based on a view point, as in this case the point is the lower-right corner of RadRichTextBox.
    var width = this.radRichTextBox.ViewportWidth;
    var heigth = this.radRichTextBox.ViewportHeight;
    Point p = new Point(width, heigth);
     
    DocumentPosition pos = this.radRichTextBox.ActiveEditorPresenter.GetDocumentPositionFromViewPoint(p);

    Note that this approach might require some adjusting, as generally the control is not prepared for this scenario.

    I hope this is useful.

    Regards,
    Petya
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  8. Peter
    Peter avatar
    13 posts
    Member since:
    Feb 2014

    Posted 07 Aug 2014 in reply to Petya Link to this post

    Thanks Petya,

    We are not making the RadRichTextBox controls editable as they are just rendered as part of a larger overall view and then a pdf (or other format) report is created from that.  I was originally using the WPF RichTextBox to display in this code.  But, we use the RadRichTextBox in our application for editing and I noticed that there were some differences in the way the rtf was displayed between the WPF control and the Telerik one, so I was forced to switch this view to also use the RadRichTextBox.

    I had already determined that creating a separate RadDocument for each instance of the control was the way to go.  Now, after I determine the display positions for each instance of the control, I am trying to insert bookmarks at each place that I want to scroll to in the document. Does that seem like a reasonable solution?  Should the GoToBookmark method move the caret the same way the the Move..() methods on DocumentPosition do?

    Thanks,

    Peter
  9. Kammen
    Admin
    Kammen avatar
    312 posts

    Posted 12 Aug 2014 Link to this post

    Hi Peter,

    You are correct. The GoToBookmark method internally moves the CaretPosition to the position of the bookmark.

    If you have other questions do not hesitate to contact us.

    Regards,
    Kammen
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  10. Peter
    Peter avatar
    13 posts
    Member since:
    Feb 2014

    Posted 12 Aug 2014 in reply to Kammen Link to this post

    Thanks, Kammen.

    I have been trying to use the GoToBookmark method, via a RadDocumentEditor.Document object.  Then I set the RadDocument in my RadRichTextBox control, but the document is not positioned in the RadRichTextBox exactly at the bookmark I set.

    I think that the bookmark should be at the bottom of the viewable area of radrichtextbox, but there are lines showing below the bookmark, which pushes lines that should be showing at the top of the radrichtextbox out of the visible area.

    Petya made this comment in an earlier post: "Note that this approach might require some adjusting, as generally the control is not prepared for this scenario."

    Could you be more specific as to what type of adjustments can be made so that I can position the document exactly where I need it in the radrichtextbox?

    Thanks,

    Peter
  11. Kammen
    Admin
    Kammen avatar
    312 posts

    Posted 13 Aug 2014 Link to this post

    Hello Peter,

    I think that what Petya meant was that RadRichTextBox does not have a position at the end of the line. If you click there, the caret position is moved at the beginning of the next line. So this could explain why the content is scrolled more than expected when moving to a bookmark. You could try to use any other position from the last line to put your bookmark there, just don't use the last. This should work.

    Hope this will make it work.


    Regards,
    Kammen
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
  12. Peter
    Peter avatar
    13 posts
    Member since:
    Feb 2014

    Posted 14 Aug 2014 in reply to Kammen Link to this post

    Thanks Kammen,

    Unfortunately I'm still not able to get the document positioned in the control as precisely as I need it.

    I have created a sample app to demonstrate the issue I'm having.  I've tried your suggestion of moving the bookmark away from the end of a line, but it doesn't seem to change my results.  When I use the GoToBookmark method, I would expect the bookmark to be in the bottom most viewable position in the control, but there always seems to be an extra line or two visible below the bookmark.

    If you run the sample app, you should see the same results that I am seeing.  If so, maybe you can offer some suggestions as to how to better position the RadDocument.

    However, the file attachment here won't allow me to upload a .zip file.  Can you advise on how to submit the sample application code to you?

    Thanks,

    Peter
  13. Kammen
    Admin
    Kammen avatar
    312 posts

    Posted 19 Aug 2014 Link to this post

    Hi Peter,

    As I said in the ticket that you have opened I think that this difference is caused by the resizing the RadRichTextBox when shown. It seems that the document is not measured correctly. If you set the document and execute the GoToBookmark action after the control is measured and arranged, everything should work as expected.

    Hope this answers your question.

    Regards,
    Kammen
    Telerik
     
    Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
     
Back to Top
UI for WPF is Visual Studio 2017 Ready