VSTO Word 加载项:如何在数组单元格中添加内容控件

VSTO Word Add-In: How to add a content control in a array cell

我正在构建一个 VSTO Word 加载项,它会在单击它时创建一个数组。我想在其中一个数组单元格中添加一些文本、一个新行和一个富文本内容控件。

我已经通过使用以下代码设法让它工作:

Word.Table table = Globals.MyAddIn.Application.ActiveDocument.Tables.Add(currentRange, 8, 3, ref missing, ref missing);
range = table.Cell(1, 3).Range;
range.Text = "SomeText" + Environment.NewLine;
range.MoveStartUntil(Environment.NewLine, Word.WdConstants.wdForward);
range.MoveStart(Word.WdUnits.wdCharacter, 1);
range.MoveEnd(Word.WdUnits.wdCharacter, -1);
Word.ContentControl cc = range.ContentControls.Add();
cc.Tag = "someTag";

我不明白为什么需要 "MoveStart" 和 "MoveEnd" 指令而不是仅使用 "MoveStartUntil" 指令。有更好的方法吗?

另外,我想在我写的文本上添加粗体效果,而不是在内容控制字段中写入的文本上。我尝试添加以下代码,但它适用于所有单元格,而不仅仅是我的文本。

range.Bold = 1;

我猜你遇到了换行问题。在这种情况下,您最好的方法是在代码运行时逐步检查代码,并在每一步检查 Text 的值(我通常发现自己无论如何都必须这样做,只是为了让事情正常进行)。

Word.Table table = Globals.MyAddIn.Application.ActiveDocument.Tables.Add(currentRange, 8, 3, ref missing, ref missing);
range = table.Cell(1, 3).Range;
// The text here starts as "\r\a"; if you turn on paragraph marks you will see an icon in each table cell; this must be that character

range.Text = "SomeText" + Environment.NewLine;
// Now the text is now "SomeText\r\r\a" (NewLine is "\r\n" and I think "\n" gets converted to "\r")
// Note that Word will put \r or \a back if you omit them, since you're in a table cell

range.MoveStartUntil(Environment.NewLine, Word.WdConstants.wdForward);
// Now it's "\r\r\a"

range.MoveStart(Word.WdUnits.wdCharacter, 1);
// "\r\a"

range.MoveEnd(Word.WdUnits.wdCharacter, -1);
// finally the text is null (because it's a 0-length range), and in the needed location

Word.ContentControl cc = range.ContentControls.Add();
cc.Tag = "someTag";

您还想将第一行设为粗体,但在这些步骤的 none 中仅选择了文本 "SomeText"(您需要省略尾随字符,或之前插入的任何内容它们也将具有指定的格式),因此您必须稍微修改一下才能使用 range.Bold = 1.

这是您可以做到的方式:

Range currentRange = Paragraphs[3].Range;
Table table = Tables.Add(currentRange, 8, 3, ref missing, ref missing);
Range range = table.Cell(1, 3).Range;
// Starts as "\r\a"

range.Text = "SomeText";
// The text is now "SomeText\r\a"

range.MoveEnd(WdUnits.wdCharacter, -1);
// "SomeText"

range.Bold = 1;
range.InsertParagraphAfter();
// "SomeText\r" (this puts the paragraph mark inside the current range which is kind of counter-intuitive)

range.Collapse(WdCollapseDirection.wdCollapseEnd);
// This is the new paragraph

Interop.ContentControl cc = range.ContentControls.Add();
cc.Tag = "someTag";

您显示的代码是正确的,只是如何使用 Range 对象的问题。当然有不止一种方法。下面的代码示例是我的偏好。

基本上,你想做三件事,所以你需要对目标Range进行三次操作:文本+粗体;新段落;添加内容控件。

使用范围然后向其添加内容的关键是 折叠 范围。可以把它想象成按键盘上的右箭头键将选择折叠到闪烁的插入点。对范围也需要做同样的事情;您使用 Collapse 方法,折叠到终点(也可以选择折叠到起点)。

将文本放入范围内,然后进行所需的任何格式设置。然后插入段落标记,之后需要再次折叠 Range。 Table 单元格是一种特殊情况:当折叠到 table 单元格末尾时,焦点最终出现在下一个单元格中。所以需要后退一个字符。

然后添加内容控件即可。

    object oCollapseEnd = Word.WdCollapseDirection.wdCollapseEnd;
    rng.Collapse(ref oCollapseEnd);
    Word.Table table = doc.Tables.Add(rng, 8, 3, ref missing, ref missing);
    Word.Range range = table.Cell(1, 3).Range;
    range.Text = "SomeText";
    range.Font.Bold = -1;
    range.InsertAfter(Environment.NewLine);
    range.Collapse(ref oCollapseEnd);
    range.MoveEnd(Word.WdUnits.wdCharacter, -1);
    Word.ContentControl cc = range.ContentControls.Add();
    cc.Tag = "someTag";