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

MergeField in Header and Footer

5 Answers 156 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Cameron Molyneux
Top achievements
Rank 1
Cameron Molyneux asked on 27 Feb 2012, 03:44 PM
Hi,

We have a custom MergeField and are unable to place them inside the Header or Footer in the document. We drag and drop MergeFields into the document where the cursor is, and if I place my cursor in the Header or Footer, it is simply placed at the top of the document.

Thanks.

5 Answers, 1 is accepted

Sort by
0
Iva Toteva
Telerik team
answered on 01 Mar 2012, 11:12 AM
Hello Cameron,

I guess you are using the InsertField method of your main RadRichTextBox editor to insert the merge fields in the document. In 2012 Q1 we introduced a property of RadRichTextBox called ActiveDocumentEditor, which you should use if you want to insert something in the header/footer when in header/footer edit mode.

Here is how you can use it to insert a custom field:

this.editor.ActiveDocumentEditor.InsertField(new CustomField());

I hope this helps.

Greetings,
Iva Toteva
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Cameron Molyneux
Top achievements
Rank 1
answered on 01 Mar 2012, 05:21 PM
Hi Iva,

Using ActiveDocumentEditor.InsertField works for Headers and Footers so thank you.

However, I am using a method provided by Telerik that loops through all the mergefields in a document (See below)

private List<FieldRangeStart> GetAllMergeFields(RadDocument document)
{
    List<FieldRangeStart> mergeFields = new List<FieldRangeStart>();
    foreach (FieldRangeStart fieldStart in document.EnumerateChildrenOfType<FieldRangeStart>())
    {
        if (fieldStart.Field is MergeField)
        {
            mergeFields.Add(fieldStart);
        }
    }
    return mergeFields;
}

This method only returns the mergefields outside of the header and footer. Is there a way to retrieve all of the fields?

Thanks.
0
Martin Ivanov
Telerik team
answered on 02 Mar 2012, 03:15 PM
Hello Cameron,

The headers and footers of the document are shown in separate RadRichTextBoxes, so if you want to be able to get the merge fields from them as well, you should traverse trough all headers and footers. Here is a sample code doing this:

private void GetAllMergeFieldsInHeadersAndFooters_Click(object sender, RoutedEventArgs e)
{
    HashSet<FieldRangeStart> mergeFieldsInHeadersAndFooters = new HashSet<FieldRangeStart>();
    List<FieldRangeStart> mergeRangesInCurrenEditor;
    foreach (Section section in this.editor.Document.Sections)
    {
        RadDocument defaultHeaderBody = section.Headers.Default.Body;
        if (defaultHeaderBody != null)
        {
            mergeRangesInCurrenEditor = GetAllMergeFields(defaultHeaderBody);
            mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
        }
        RadDocument defaultFooterBody = section.Footers.Default.Body;
        if (defaultFooterBody != null)
        {
            mergeRangesInCurrenEditor = GetAllMergeFields(defaultFooterBody);
            mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
        }
        if (section.HasDifferentFirstPageHeaderFooter)
        {
            RadDocument firstPageHeaderBody = section.Headers.First.Body;
            if (firstPageHeaderBody != null)
            {
                mergeRangesInCurrenEditor = GetAllMergeFields(firstPageHeaderBody);
                mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
            }
            RadDocument frstPageFooterBody = section.Footers.Default.Body;
            if (frstPageFooterBody != null)
            {
                mergeRangesInCurrenEditor = GetAllMergeFields(frstPageFooterBody);
                mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
            }
        }
 
        RadDocument evenPageHeaderBody = section.Headers.Even.Body;
        if (evenPageHeaderBody != null)
        {
            mergeRangesInCurrenEditor = GetAllMergeFields(evenPageHeaderBody);
            mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
        }
        RadDocument evenPageFooterBody = section.Footers.Even.Body;
        if (evenPageFooterBody != null)
        {
            mergeRangesInCurrenEditor = GetAllMergeFields(evenPageFooterBody);
            mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
        }
    }


If you have any other questions, do not hesitate to contact us again. Kind regards,
Martin
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Cameron Molyneux
Top achievements
Rank 1
answered on 02 Mar 2012, 03:47 PM
Hi Martin,

Thank you for your quick response, your code works to retrieve the fields in the header and footer :)

Two more questions regarding MergeFields however...

I want to have a click event on the MergeField, so that when it is left clicked, it is replaced by either a textbox or combobox.

I'm not sure how to go about getting an instance of the field at the cursor's position.

Finally, I am performing a custom mailmerge, and have it working for the mergefields in the body of the document, but not for mergefields in the header and footer.

I am using  documenteditor.document.ChangeAllFieldsDisplayMode(FieldDisplayMode.Result); and have tried doing the same for each of the header/footer documents created in your loop, for example
if (defaultHeaderBody != null)
       {
           mergeRangesInCurrenEditor = GetAllMergeFields(defaultHeaderBody);
           mergeFieldsInHeadersAndFooters.UnionWith(mergeRangesInCurrenEditor);
           defaultHeaderBody.ChangeAllFieldsDisplayMode(FieldDisplayMode.Result);
       }

The first time when I mailmerge, the header/footer is blank, then the second time I see the mergefield's with their default text in. As I said before the mailmerge works fine for the fields in the body.

What am I missing?

Thanks.
0
Iva Toteva
Telerik team
answered on 07 Mar 2012, 08:41 PM
Hello Cameron,

You can get the field range at the caret position, check for merge fields and substitute them with a TextBox in an InlineUIContainer in the following way:

void radRichTextBox1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    double width = 100;
    double height = 20;
    DocumentPosition newCaretPosition = this.radRichTextBox1.ActiveEditorPresenter.GetDocumentPositionFromViewPoint(e.GetPosition(this.radRichTextBox1));
    this.radRichTextBox1.Document.CaretPosition.MoveToPosition(newCaretPosition);
    Inline currentInline = this.radRichTextBox1.Document.CaretPosition.GetCurrentInlineBox().AssociatedInline;
    IEnumerable<FieldRangeStart> ranges = this.radRichTextBox1.Document.GetContainingAnnotationRanges<FieldRangeStart>(currentInline, annotation => annotation.Field is MergeField);
    if (ranges.Count() != 0)
    {
        this.radRichTextBox1.Document.Selection.SelectAnnotationRange(ranges.ElementAt(0));
        InlineUIContainer container = new InlineUIContainer(new TextBox() { Width = width, Height = height }, new Size(width, height));
        this.radRichTextBox1.InsertInline(container);
    }
}

Changing the display mode of all fields can be done using the method of RadRichTextBox:
this.radRichTextBox1.ChangeAllFieldsDisplayMode(FieldDisplayMode.Result);

I hope this helps.

Regards,
Iva Toteva
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Tags
RichTextBox
Asked by
Cameron Molyneux
Top achievements
Rank 1
Answers by
Iva Toteva
Telerik team
Cameron Molyneux
Top achievements
Rank 1
Martin Ivanov
Telerik team
Share this question
or