Hi,
I import an existing word-doc that contains several bookmarks:
// import word-doc to RadFlowDocument
RadFlowDocument templateDocument = provider.Import(fileMemoryStream);
// edit RadFlowDocument
RadFlowDocumentEditor editor = new RadFlowDocumentEditor(templateDocument);
Then I modify the RadFlowDocument (inserting text, tables, ... at certain positions) by using the RadFlowDocumentEditor.
Finally, I need to remove/delete some parts of the document that are between two bookmarks. I have searched the documentation and forums but could not find a way how to do this.
Any help would be appreciated.
Regards, Manu
7 Answers, 1 is accepted
To achieve that, you will need to obtain the start of the bookmark and start deleting the following elements until you reach the start of the next bookmark. Here is a sample code of how this could be achieved:
RadFlowDocumentEditor editor =
new
RadFlowDocumentEditor(
this
.document);
editor.DeleteBookmark(
"_GoBack"
);
// When working in MS Word, an additional bookmark is inserted in the document to preserve the caret position and restore it the next time the users open the document. This line removes this bookmark.
var bookmarkStart =
this
.document.EnumerateChildrenOfType<BookmarkRangeStart>().First();
InlineBase currentElement = bookmarkStart;
var currentParagraph = currentElement.Paragraph;
var currentIndex = currentParagraph.Inlines.IndexOf(currentElement) + 1;
currentElement = currentParagraph.Inlines[currentIndex];
while
(!(currentElement
is
BookmarkRangeStart))
{
currentIndex = currentParagraph.Inlines.IndexOf(currentElement);
if
(!(currentElement
is
AnnotationMarkerBase))
{
currentElement.Paragraph.Inlines.Remove(currentElement);
if
(currentParagraph.Inlines.Count == 0)
{
var currentSection = currentParagraph.Parent
as
Section;
var nextParagraphIndex = currentSection.Blocks.IndexOf(currentParagraph);
currentSection.Blocks.Remove(currentParagraph);
currentParagraph = currentSection.Blocks[nextParagraphIndex]
as
Paragraph;
currentElement = currentParagraph.Inlines.First();
currentIndex = 0;
continue
;
}
}
else
{
currentIndex++;
}
if
(currentIndex < currentParagraph.Inlines.Count)
{
currentElement = currentParagraph.Inlines[currentIndex];
}
else
{
var currentSection = currentParagraph.Parent
as
Section;
currentParagraph = currentSection.Blocks[currentSection.Blocks.IndexOf(currentParagraph) + 1]
as
Paragraph;
currentElement = currentParagraph.Inlines.First();
}
}
Please, note that the sample removes the content between the first and the second bookmarks in a document and you would most probably need to adjust the code according to the specific requirements of the scenario.
Hope this is helpful.
Regards,
Tanya
Progress Telerik

Hi Tanya,
thank you for your help. Since there are a few other bookmarks between the starter- (first in your code) and the terminal-bookmark (second in your code) in my word-doc, I have to adjust your code.
However, I do not completely understand your code yet. I know how to set the variable for the bookmarkStart (which is the starter-bookmark), but I do not understand with what part(s) of your code the terminal-bookmark is represented.
Could you please help me with this again.
Regards, Manu
I am sorry if I wasn't clear enough in my previous reply.
The execution of the while-loop is terminated when the logic finds the next BookmarkRangeStart object. This is defined in the condition of the while-loop:
while
(!(currentElement
is
BookmarkRangeStart))
In other words, the code begins executing with the bookmark start which is passed to it as the first bookmark and ends the removing of content when it gets to the next bookmark start. If you pass the fourth bookmark start, the logic should remove the content up to the next (fifth) bookmark start.
Hope this makes things clear.
Regards,
Tanya
Progress Telerik

Hi Tanya,
I almost got it to work. In my test document I have 5 bookmarks (each on an extra row at the left page margin followed by some text and a paragraph marker).
Below my code for removing everything between the first and fith bookmark:
var bookmarkFirst = editor.Document.EnumerateChildrenOfType<
BookmarkRangeStart
>().Where(rangeStart => rangeStart.Bookmark.Name == "First").FirstOrDefault();
var bookmarkLast = editor.Document.EnumerateChildrenOfType<
BookmarkRangeStart
>().Where(rangeStart => rangeStart.Bookmark.Name == "Fith").FirstOrDefault();
InlineBase currentElement = bookmarkFirst;
var currentParagraph = currentElement.Paragraph;
var currentIndex = currentParagraph.Inlines.IndexOf(currentElement) + 1;
currentElement = currentParagraph.Inlines[currentIndex];
InlineBase lastElement = bookmarkLast;
var lastParagraph = lastElement.Paragraph;
var lastIndex = lastParagraph.Inlines.IndexOf(lastElement) + 1;
lastElement = lastParagraph.Inlines[lastIndex];
//while (!(currentElement is BookmarkRangeStart))
while ((currentElement != lastElement))
{
currentIndex = currentParagraph.Inlines.IndexOf(currentElement);
if (!(currentElement is AnnotationMarkerBase))
{
currentElement.Paragraph.Inlines.Remove(currentElement);
if (currentParagraph.Inlines.Count == 0)
{
var currentSection = currentParagraph.Parent as Section;
var nextParagraphIndex = currentSection.Blocks.IndexOf(currentParagraph);
currentSection.Blocks.Remove(currentParagraph);
currentParagraph = currentSection.Blocks[nextParagraphIndex] as Paragraph;
currentElement = currentParagraph.Inlines.First();
currentIndex = 0;
continue;
}
}
else
{
currentIndex++;
}
if (currentIndex < currentParagraph.Inlines.Count)
{
currentElement = currentParagraph.Inlines[currentIndex];
}
else
{
var currentSection = currentParagraph.Parent as Section;
currentParagraph = currentSection.Blocks[currentSection.Blocks.IndexOf(currentParagraph) + 1] as Paragraph;
currentElement = currentParagraph.Inlines.First();
}
}
I have several issues left:
- The code removes all text between bookmarkFirst and bookmarkLast, but the bookmarks in between (2nd,3rd and 4th) including the corresponding empty paragraphs are left. I need to remove 'everything' (tables, paragraphs, text, ...) in between.
- When a table or an empty paragraph is in between bookmarkFirst and bookmarkLast I get an error at:
else
{
var currentSection = currentParagraph.Parent as Section;
currentParagraph = currentSection.Blocks[currentSection.Blocks.IndexOf(currentParagraph) + 1] as Paragraph;
currentElement = currentParagraph.Inlines.First(); // here the error happens
}
I also tested your original code and obtained the same errors when a table or an empty paragraph is in between bookmarkStarter and the next bookmark.
I hope, you can find a fix for these issues.
Regards, Manu
The error you are getting is as a result of the fact that the Inlines collection of the paragraph is empty and an element cannot be obtained from it. The other error is thrown because the element being currently iterated is not a Paragraph but a Table, resulting in a null value for the currentParagraph variable. I modified the code a bit to avoid similar issues. You can find it attached to this reply.
Hope this helps.
Regards,
Tanya
Progress Telerik

Hi Tanya,
thank you again. Now it works.
As a side-note:
editor.DeleteBookmark("_GoBack")
always gives an error with my Word-doc template (that I import to RadFlowEditor) regardless of how often I have modified/saved it.
Regards, Manu
Thank you for writing back - I am happy to hear that everything is now working as expected.
I added the invocation of the DeleteBookmark() at the beginning just to ensure there are no additional bookmarks added by MS Word. In case the documents you are working with don't include such objects, you can remove this line. Or, if you would like to preserve it, you can check if such a bookmark is available before trying to delete it.
Hope this is helpful.
Regards,
Tanya
Progress Telerik