Word VSTO 加载项:通过其范围更改段落的文本

我正在编写一个加载项,它使用 GroupContentControl (GCC) 来写保护使用“标题 1”样式的每个段落。一旦受到保护,这些标题只能通过加载项进行更改。为此,我编写了一个简单的方法,删除段落的 GCC,为段落的 Range.Text 属性分配一个新值,再次将样式设置为标题 1,然后设置一个新的 GCC 来保护该段落。


我还是 Office 编程的新手,我的假设是 Range 对象可以在整个过程中使用。但是,该方法行为不端:它在新段落文本后插入回车符,然后将文档中的下一段设为标题 1 段落,然后对其进行写保护。


这是我的方法,以及对日志函数的调用以查看范围如何演变:


void ChangeParagraphText (Word.Paragraph p, string NewText)

{

    Log("Range 1 : " + p.Range.Start + " - " + p.Range.End);

    UnlockTitle(p);     // remove the paragraph's GroupContentControl     

    Log("Range 2 : " + p.Range.Start + " - " + p.Range.End);

    p.Range.Text = NewText;   // change the paragraph's text

    Log("Range 3 : " + p.Range.Start + " - " + p.Range.End);

    p.Range.set_Style(Globals.ThisAddIn.Application.ActiveDocument.Styles[Word.WdBuiltinStyle.wdStyleHeading1]);

    Log("Range 4 : " + p.Range.Start + " - " + p.Range.End);

    LockTitle(p);       // write-protect the paragraph with a GroupContentControl

    Log("Range 5 : " + p.Range.Start + " - " + p.Range.End);

}

运行后,以下是日志文件的内容:


Range 1 : 90 - 99

Range 2 : 90 - 97

Range 3 : 100 - 102

Range 4 : 100 - 102

Range 5 : 100 - 104

这教会了我一些有趣的事情。对于初学者来说,去掉GCC后Range的长度减少2,增加GCC时增加2。然而,重要的部分是第三个日志条目:它表明,一旦我分配了段落的 Range.Text,范围就完全改变了。这些值与我的测试文档中的下一段相匹配。


读取 Range.Text 属性还显示它以换行符 (ASCII 13) 结尾。如果我省略它,我最终会将下一段附加到我的标题 1 段落。如果我把它放进去,我最终会将第二段视为标题 1 段。这些行为都不适合我。


我的问题是:如何以编程方式更改段落的文本?我认为它必须是可能的,但如果不是,有什么解决方法?我一直想在我想更改的段落之后创建一个新段落,然后删除旧段落,但这似乎不雅。


白衣染霜花
浏览 257回答 1
1回答

qq_遁去的一_1

首先,快速回答您提出的问题:如何在保持段落本身完整的同时替换段落的文本。我无法使用您提供的代码,因为它没有显示您如何导出p. 所以我拿了一个任意的Paragraph对象:Word.Range rngPara = doc.Paragraphs[1].Range;object unitCharacter = Word.WdUnits.wdCharacter;object backOne = -1;rngPara.MoveEnd(ref unitCharacter, ref backOne);rngPara.Text = "replacement text";背景资料:问题最重要的方面是理解 WordRange对象。首先,永远不要依赖Start和End属性来识别范围。它们适用于“快照”,或者将一个范围的起点或终点动态设置为一秒的起点或终点。但是,只要在文档中进行了任何编辑,您就可以将它们扔掉。当您需要使用范围时,请Range在运行代码期间使用对象(变量)。是的,正如您分析的那样,Paragraph.Range.Text确实包括段尾标记。这是 ANSI 13,不仅仅是一个回车;在幕后,它存储了有关段落格式的大量信息。如果您只想处理文本,请将范围缩短一个字符以将段落标记保留在范围之外。这可以使用该MoveEnd方法来完成。
打开App,查看更多内容
随时随地看视频慕课网APP