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
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
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.
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
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.
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.
Iva Toteva
the Telerik team