RadRichTextbox - uneditable header footer AND sidebar

8 posts, 0 answers
  1. ric
    ric avatar
    22 posts
    Member since:
    Apr 2011

    Posted 26 Jul 2013 Link to this post

    as per subject, we are developing a reporting aspect of our application but the report pages require a template that includes a header, footer and a sidebar - imagine the editable "main" document area taking place inside a letter "C". We want to allow the user to edit the main content to their heart's content but the images/text in the template must not be editable

    I'm aware that document protection might get me some of the way there but the sidebar may be a sticking point, e.g. if the user inserts a page i don't want them to end up with a blank page, need a way of asserting the entire template is present 

    another potential issue is that the front/first page often has a different layout / template

    Any ideas? I'm not above customising the DocumentPagePresenter to "fake" the template and then insert the real elements into the final pdf after the fact but ideally I'd like to just have everything really actually in the document.
  2. ric
    ric avatar
    22 posts
    Member since:
    Apr 2011

    Posted 29 Jul 2013 Link to this post

    I have a new idea, which is to insert floating block elements into each page (behind-text). This works fine. Problem I have is that when a new page is inserted due to wrapping or an inserted page break I now have a blank page. I'm hoping for something along the lines of a newPageInserted event so that I can go ahead and stuff my components in?
  3. DevCraft banner
  4. Iva Toteva
    Admin
    Iva Toteva avatar
    1319 posts

    Posted 30 Jul 2013 Link to this post

    Hello Ric,

    There is no event that is fired when a new page is added to the document. The only thing that comes to mind is to use the DocumentContentChanged event which is fired asynchronously on every change in the content of the document. Then, in the handler count the number of pages and compare it to the previous value, something in the lines of:

    int previousPageNumber = 1;
    void radRichTextBox_DocumentContentChanged(object sender, EventArgs e)
    {
        int pageNumber = 0;
        foreach (var section in this.radRichTextBox.Document.Sections)
        {
            pageNumber += section.GetAssociatedLayoutBoxes().Count();
        }
        if (pageNumber != previousPageNumber)
        {
            Debug.WriteLine(pageNumber - previousPageNumber + " pages added");
            previousPageNumber = pageNumber;
        }
    }

    Note that this event will be fired even when you add the image (as it is a change in the document). Thus, it is not recommended to invoke actions that can cause a cycle (in this case actions that change the page number, floating images should be OK).

    I hope this answers your question.

    Regards,
    Iva Toteva
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  5. ric
    ric avatar
    22 posts
    Member since:
    Apr 2011

    Posted 01 Aug 2013 Link to this post

    Thanks that does help, and I've gotten around the layout-cycle issue. Next problem is that there doesn't seem to be a simple way to iterate through the pages, can't do

    foreach( p in document.pages )
    {
     p.insert(x)
    }

    And once I've inserted a Floating element there appears to be no way of checking a page on the next run-through to see if it has been "done" previously as the floating elements don't appear in the children collection?

    And  because there are no "page" objects I can't make a dictionary<page,image> to keep track of this myself either

    Closest I came was tracking the page LayoutBoxes, but these seem to get created and destroyed by the editor

    anyway, end result is that I end up with multiple background images on each page!

    Right now I'm at the stage where I want an entire XAML element containing text, images and lines/colours to sit "behind" the editable document (with a first-page variation). So that it's there when you print, but you can't edit it. The Floating elements seem to be the way to go but as you can see I'm still a long way off!
  6. Iva Toteva
    Admin
    Iva Toteva avatar
    1319 posts

    Posted 06 Aug 2013 Link to this post

    Hello Ric,

    Indeed there will not be an easy way to track where the new pages have been added or which pages have been removed in order to add/remove the floating images on the fly.

    If it were for showing just images, perhaps a better approach would be to use watermarks. Watermarks are kept in the headers, so you can have different watermarks for each different section. In addition, in each section, you can have a different first page, odd and even headers. Please find attached a document that has two pages (one section only) with different first and second page watermarks.

    With regard to your comment that you would like to have an entire page (XAML element) with some content "behind" the editable content, I am afraid that this will not be possible using RadRichTextBox.

    Regards,
    Iva Toteva
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  7. ric
    ric avatar
    22 posts
    Member since:
    Apr 2011

    Posted 07 Aug 2013 Link to this post

    I have had partial success with creating and populating a Canvas element and then inserting that as a FloatingUIElement in the page. This exports to PDF and prints out successfully, which is perfect for my needs.

    I understand that the document itself has limited knowledge of pages, if there were a way of remembering/tracking each FloatingUIElement in the document (DocumentPosition?) then I'd be able to do something like this (psudeocode)

    if( newPageCount <> oldPageCount )
    {
        for each floaty in previouslyAppliedFloatingElements
        {
           document.remove(floaty)
        }
          previouslyAppliedFloatingElements.Clear()
     
        for i = 1 to newPageCount
        {
            document.CaretPosition.MoveToPage()
               TemplateThing t = new TemplateThing()
               previouslyAppliedFloatingElements.Add(t)
            document.InsertInline(t)
        }
    }

    Ideally I'd be able to track down my FloatingUIElements by walking the document structure, but they must be buried somewhere because I can't find them once I've added them?!
  8. Iva Toteva
    Admin
    Iva Toteva avatar
    1319 posts

    Posted 12 Aug 2013 Link to this post

    Hi Ric,

    With this approach there is no way to track the inserted floating elements. The only suggestion we have is to use images instead of floating InlineUIContainers and set them as watermarks.

    Regards,
    Iva Toteva
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for SILVERLIGHT.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  9. ric
    ric avatar
    22 posts
    Member since:
    Apr 2011

    Posted 13 Aug 2013 Link to this post

    Hi, well I found a solution. One is to have a timer that every fraction of a second loops through the editor's visible page presenter controls and inserts Canvas elements directly into them, tracking them as they're created and destroyed.

    then when the user presses print or save I make a copy of the document, place that into another, hidden editor control, and for-each the pages inserting the same canvasses as floatingUIElements (knowing that at this point no pages will be added or removed so I don't need to track them), before doing the actual print/save.

    Bit of a long way around, by my "create template / background canvas" code is shared between both routines, keeping the complexity down a little!

Back to Top
DevCraft banner