Setting HighlightColor in MergeFields misses the first 2 words

I am using the code below to highlight text in merge fields as yellow. In all of the merge fields all of the text after the first 2 words is highlighted. The first 2 words remain un-highlighted. Am I doing something incorrectly? Is there a better way to achieve this?

    public class AsposeCallBackHandler : IFieldMergingCallback
    {
        public void FieldMerging(FieldMergingArgs args)
        {
            if (args.Field.Start != null)
            {
                // Get the NextSibling node and keep looping until we find the FieldEnd node.
                Node ThisNode = args.Field.Start;

                while (ThisNode != null && ThisNode.NodeType != NodeType.FieldEnd)
                {
                    // Run nodes get the formatting.
                    if (ThisNode.NodeType == NodeType.Run)
                    {
                        var ThisRun = ((Run)ThisNode);

                        // Set the background color to yellow.
                        ThisRun.Font.HighlightColor = System.Drawing.Color.Yellow;
                    }

                    ThisNode = ThisNode.NextSibling;
                }
            }
        }

        public void ImageFieldMerging(ImageFieldMergingArgs args)
        {
        }
    }

@JohnGSS,

Thanks for your inquiry. To ensure a timely and accurate response, please ZIP and attach the following resources here for testing:

  • Your simplified input Word document
  • Aspose.Words 18.9 generated output DOCX file showing the undesired behavior
  • Your expected DOCX Word document showing the correct output. You can create expected document by using Microsoft Word.
  • Please also create a standalone simple console application (source code without compilation errors) that helps us to reproduce your current problem on our end and attach it here for testing. Please do not include Aspose.Words.dll files in it to reduce the file size.

As soon as you get these pieces of information ready, we will start investigation into your issue and provide you code to achieve the same by using Aspose.Words. Thanks for your cooperation.

I have uploaded a zip file containing the console application and Word documents in the Documents folder.

While creating this project it became apparent what is happening. When I create the MergeField using Word Insert->Quick Parts->Field from the tool bar it includes MERGEFORMAT in the MergeField. Fields created this way exhibit the problem. Fields created using CTRL-F9 and entering the field name without MERGEFORMAT work as expected. Removing MERGEFORMAT from the ones created through the toolbar makes them work as expected.

Removing MERGEFORMAT as a work around in development is reasonable, but I can’t control how others will create MergeFields in production.

Your help is greatly appreciated.

@JohnGSS,

I am afraid, we do not see any new attachments in this thread. If your file size is big then you may upload the ZIP file to Dropbox or any other file hosting service and share the download link here for testing.

You can find the ZIP file here: Dropbox - File Deleted - Simplify your life

@JohnGSS,

We are working on your query and will get back to you soon.

@JohnGSS,

To workaround this problem, please pre-process your document before executing mail merge.

List<string> DataColumnNames = new List<string>();
List<string> DataValues = new List<string>();

DataColumnNames.Add("CompanyName");
DataColumnNames.Add("ShortString");
DataColumnNames.Add("Summary");

DataValues.Add("My Company Name");
DataValues.Add("X Y Z");
DataValues.Add("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque nec nulla quam. Nulla tellus justo, sollicitudin eu malesuada non, porttitor in eros. Quisque eget mauris ut quam commodo gravida. Quisque sit amet erat sapien. Cras sit amet nisi sit amet leo pellentesque gravida.");

Document BaseTemplate = new Document("D:\\temp\\Aspose.Words.Test\\AsposeTest.docx");

foreach (Field field in BaseTemplate.Range.Fields)
{
    if (field.Type.Equals(FieldType.FieldMergeField))
    {
        Node currentNode = field.Start;
        bool isContinue = true;

        while (currentNode != null && isContinue)
        {
            if (currentNode.NodeType.Equals(NodeType.FieldEnd))
                isContinue = false;

            if (currentNode.NodeType.Equals(NodeType.Run))
            {
                Run run = (Run)currentNode;
                run.Font.HighlightColor = Color.Red;
                //break;
            }

            Node nextNode = currentNode.NextPreOrder(currentNode.Document);
            currentNode = nextNode;
        }
    }
}

DocumentBuilder BaseTemplateBuilder = new DocumentBuilder(BaseTemplate);
bindDocumentData(BaseTemplate, DataColumnNames, DataValues); 

After that you do not need to ‘AsposeCallBackHandler’ class. Hope, this helps.

Thank you for your quick response. This method works fine for the simplified example project but what I am doing is a bit more complicated than highlighting all fields in the document. I need to selectively highlight fields depending on another value. The fields could be single fields or fields in a table where each row may have different highlighting requirements. It may be bound using Arrays or a DataSet. I have modified the project to show this using arrays. It is located here: Dropbox - File Deleted - Simplify your life

@JohnGSS,

Yes, you can pass the data source to the constructor of AsposeCallBackHandler class and then inside FieldMerging event make the decision on the current field based on the value of data source. Hope, this helps.

I know I should be able do it that way but it doesn’t work properly. When I try to apply highlighting in the FieldMerging event I get the problem that I was originally asking about. “All but the first 2 words get highlighted”.

@JohnGSS,

To get the desired output, you can simply remove the MERGEFORMAT switch by using the following code. Hope, this helps.

...
...
Document BaseTemplate = new Document("D:\\temp\\Aspose.Words.Test\\AsposeTest.docx");
DocumentBuilder BaseTemplateBuilder = new DocumentBuilder(BaseTemplate);

foreach (Field field in BaseTemplate.Range.Fields)
{
    if (field.Type.Equals(FieldType.FieldMergeField))
    {
        FieldMergeField mf = (FieldMergeField)field;
        mf.Format.GeneralFormats.Remove(GeneralFormat.MergeFormat);
    }
}

bindDocumentData(BaseTemplate, DataColumnNames, DataValues);
...

Thanks, that does solve my problem. Is this considered a bug? If so is there a plan to fix it in future releases? Or will I need to use this work-around in all future projects?

@JohnGSS,

This is not a bug in Aspose.Words API. The MERGEFORMAT switch was prohibiting the new font formatting. Yes, you can remove this switch to get the desired output in your projects.