I need to insert a cover page into a Word 2016 document. The building block is a cover page and has
InsertOptions = (int)WdDocPartInsertOptions.wdInsertPage; //= 2
So far so good.
But VSTO can only insert so:
buildingBlock.Insert(range);
It does insert in place of range.
The event Application.ActiveDocument.BuildingBlockInsert
is not raised.
Using native insert cover page (tab insert --> cover page) does insert properly (and creates only one undo entry insert building block).
// -----------------------------------------------------------------
// try 1
var range = Application.ActiveDocument.Range();
range.Collapse(WdCollapseDirection.wdCollapseStart);
buildingBlock.Insert(range);
// result: inserting on the existing first page
// one undo entry
// event BuildingBlockInsert has not been raised
// -----------------------------------------------------------------
// try 2
//object start = 0;
//object end = 0;
//var range = Application.ActiveDocument.Range(ref start, ref end);
//buildingBlock.Insert(range);
// result: inserting on the existing first page
// one undo entry
// event BuildingBlockInsert has not been raised
// -----------------------------------------------------------------
// try 3
//var range = Application.ActiveDocument.Range();
//range.InsertParagraphBefore();
//var p = Application.ActiveDocument.Paragraphs[1];
//buildingBlock.Insert(p.Range);
// result: inserting on the existing first page
// two undo entries
// event BuildingBlockInsert has not been raised
// -----------------------------------------------------------------
A similar problem is described in Note of: https://learn.microsoft.com/en-us/office/vba/word/concepts/working-with-word/working-with-building-blocks#inserting-a-building-block-into-a-document
It seems VSTO ignores any insert options, and there is no way to parameterize insert option by inserting.
How can VSTO insert a building block in a new first page as a Word native action?
I'm using VS 2017 Word 2016 Add-In, .Net Framework 4.6.1.
Summary:
My current code:
private static Microsoft.Office.Interop.Word.Application Application => Globals.ThisAddIn.Application;
private void InsertCoverPage(BuildingBlock buildingBlock)
{
// validate not null
if(buildingBlock == null) throw new ArgumentNullException(nameof(buildingBlock));
// validate is a cover page
if (buildingBlock.Type.Index != (int)WdBuildingBlockTypes.wdTypeCoverPage &&
buildingBlock.Type.Index != (int)WdBuildingBlockTypes.wdTypeCustomCoverPage)
{
throw new ArgumentNullException(nameof(buildingBlock));
}
// validate insert option
if (buildingBlock.InsertOptions != (int) WdDocPartInsertOptions.wdInsertPage)
{
throw new Exception(
"building block as a cover page must been inserted in a new page at the beginning of document");
}
Application.ScreenUpdating = false;
Range range = GetCurrentCoverPageRange() ?? Application.ActiveDocument.Range(0, 0);// search a first existing cover page range
range.InsertBreak(WdBreakType.wdPageBreak); // case existing cover page: replace by page break
// range.Start = 0; // = 0
range.End = 0; // reset only end position
buildingBlock.Insert(range, true);
Marshal.ReleaseComObject(range);
Application.ScreenUpdating = true;
}
private Range GetCurrentCoverPageRange()
{
Range result = null;
// Word insert natively a cover page with 2 paragraphs - so we need found these first 2 consecutive paragraphs marked as a cover page
for (int i = 1; i < Application.ActiveDocument.Paragraphs.Count + 1; i++)
{
var paragraph = Application.ActiveDocument.Paragraphs[i];
var isCoverPage = (bool)paragraph.Range.Information[WdInformation.wdInCoverPage];
if (isCoverPage)
{
if (result == null)
{
result = paragraph.Range;
}
else
{
result.End = paragraph.Range.End;
}
}
else
{
if (result != null)
{
break;
}
}
}
return result;
}