oshirowanen
oshirowanen

Reputation: 15925

Adding formatted text to an existing bookmark

I'm trying to add some formatted text to an existing bookmark. For some reason, the formatting is not working, and the text goes outside the bookmark (right of the bookmark) instead of within the bookmark.

This is the code I have so far:

var bmkRange = this.bookmark1.Range;
object newRangeStart = bmkRange.Start;
object newRangeEnd = bmkRange.End;

Word.Range r = Range(ref newRangeStart , ref newRangeEnd);

// if ( a == b )
// {
r.Text = "some text here, ";
r.Bold = 0;
r.Font.Name = "Verdana";
r.Font.Size = 10.0F;
// }
// else if ( c == d )
// {
r.Text += "some more text here, ";
r.Bold = -1;
r.Font.Name = "Times New Roman";
r.Font.Size = 10.0F;
// }
// else if ( e == f )
// {
r.Text += "and even more text here.";
r.Bold = 0;
r.Font.Name = "Verdana";
r.Font.Size = 20.0F;
// }

I'm clearly not doing this right. Anyone have any ideas?

It's a word document level project created using visual studio 2013.

Upvotes: 0

Views: 1183

Answers (1)

Gedde
Gedde

Reputation: 1160

There are two issues with your code.

  1. The text is inserted after the bookmark.
  2. Your styles are not applied correctly.

Solution to issue #1 and #2:

This is mostly a solution to issue #2. The parts that affect issue #1 are commented in the code.

Introduce this function:

/// <summary>
/// Appends text to a range
/// </summary>
/// <param name="range">The range to insert into.</param>
/// <param name="appendText">The text to append.</param>
/// <param name="appendedRange">The range of the appended text</param>
/// <returns>
/// The range of the combined old text and the appended text
/// </returns>
private Word.Range AppendToRange(Word.Range range, string appendText, out Word.Range appendedRange)
{
    // Fetch indexes
    object oldStartPosition = range.Start;           
    object oldEndPosition = range.End;
    object newEndPosition = (int)oldEndPosition + appendText.Length;

    // Append the text
    range.InsertAfter(appendText);

    // Define the range of the appended text
    appendedRange = Range(ref oldEndPosition, ref newEndPosition);

    // Return the range of the new combined range
    return Range(ref oldStartPosition, ref newEndPosition);
}

And update your code to the following:

var bookmark = this.bookmark1;
// Solution to issue #1: Keep the name of the bookmark
var bookmarkName = bookmark.Name; 
var bmkRange = bookmark.Range;

Word.Range r;

// if ( a == b )
// {
bmkRange = AppendToRange(bmkRange, "some text here, ", out r);
r.Bold = 0;
r.Font.Name = "Verdana";
r.Font.Size = 10.0F;
// }
// else if ( c == d )
// {
bmkRange = AppendToRange(bmkRange, "some more text here, ", out r);
r.Bold = -1;
r.Font.Name = "Times New Roman";
r.Font.Size = 10.0F;
// }
// else if ( e == f )
// {
bmkRange = AppendToRange(bmkRange, "and even more text here.", out r);
r.Bold = 0;
r.Font.Name = "Verdana";
r.Font.Size = 20.0F;
// } 

// Solution to issue #1: Restore the bookmark
object newBmkRange = bmkRange;
Bookmarks.Add(bookmarkName, ref newBmkRange);

Rationale for solution to issue #1: Word will insert the text after the bookmark when you append it. Therefore you need to restore the bookmark to cover the entire range after we have done our updates. This is done by keeping track of the bookmark name and then overwriting it (effectively updating it).

Rationale for solution to issue #2: In your code example, you are styling the entire range over and over again. You need to extract the range of the appended text and style that range. This is solved with the out parameter of the provided function.

Upvotes: 1

Related Questions