Word VSTO Add-In:通过其范围更改段落的文本
Word VSTO Add-In : Changing the Text of a Paragraph through its Range
我正在编写一个 add-in,它使用 GroupContentControl (GCC) 来 write-protect 每个使用 "Heading 1" 样式的段落。一旦受到保护,这些标题只能通过 add-in 进行更改。为此,我写了一个简单的方法,删除段落的 GCC,为段落的 Range.Text 属性 分配一个新值,再次将样式设置为标题 1,然后设置一个新的 GCC 来保护段.
我对 Office 编程还是个新手,我的假设是范围 object 可以在整个过程中使用。但是,该方法行为不当:它在新段落文本后插入一个回车符 return,然后将文档中的下一段设为标题 1 段落,然后 write-protect 就可以了。
这是我的方法,以及对记录函数的调用以查看范围如何演变:
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
这让我学到了一些有趣的东西。对于初学者来说,Range 的长度在移除 GCC 后减少了两倍,在添加 GCC 后增加了两倍。不过,重要的部分是 third 日志条目:它表明一旦我分配段落的 Range.Text,范围就会完全改变。这些值与我的测试文档中的 下一个 段落匹配。
阅读 Range.Text 属性 也表明它以换行符 (ASCII 13) 结尾。如果我省略它,我会在标题 1 段落后附加下一段。如果我把它放进去,我最终会将第二段视为标题 1 段。 None 这些行为对我有用。
我的问题是:如何以编程方式更改段落的文本?我认为它必须是可能的,但如果不是,解决方法是什么?我一直想在我想改的那一段之后再新建一段,然后把旧的删掉,但是这样好像不太雅致。
首先,快速回答您提出的问题:如何在保持段落本身完整的情况下替换段落的文本。我无法使用您提供的代码,因为它没有显示您如何得出 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";
背景资料:
您的问题最重要的方面是理解 Word Range
对象。
首先,永远不要依赖 Start
和 End
属性来识别范围。它们适用于 "snapshots",或将一个范围的开始点或结束点动态设置为一秒的开始点或结束点。但是一旦在文档中进行了任何编辑,您就可以将它们丢弃。
当您需要使用范围时,请在 运行 代码期间使用 Range
对象(变量)。
是的,正如您所分析的,Paragraph.Range.Text
确实包含了段落结束标记。这是 ANSI 13,不仅仅是一个马车 return;在幕后,它存储了大量有关段落格式的信息。当您只想处理文本时,将范围缩短一个字符以将段落标记留在范围之外。这可以使用 MoveEnd
方法来完成。
我正在编写一个 add-in,它使用 GroupContentControl (GCC) 来 write-protect 每个使用 "Heading 1" 样式的段落。一旦受到保护,这些标题只能通过 add-in 进行更改。为此,我写了一个简单的方法,删除段落的 GCC,为段落的 Range.Text 属性 分配一个新值,再次将样式设置为标题 1,然后设置一个新的 GCC 来保护段.
我对 Office 编程还是个新手,我的假设是范围 object 可以在整个过程中使用。但是,该方法行为不当:它在新段落文本后插入一个回车符 return,然后将文档中的下一段设为标题 1 段落,然后 write-protect 就可以了。
这是我的方法,以及对记录函数的调用以查看范围如何演变:
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
这让我学到了一些有趣的东西。对于初学者来说,Range 的长度在移除 GCC 后减少了两倍,在添加 GCC 后增加了两倍。不过,重要的部分是 third 日志条目:它表明一旦我分配段落的 Range.Text,范围就会完全改变。这些值与我的测试文档中的 下一个 段落匹配。
阅读 Range.Text 属性 也表明它以换行符 (ASCII 13) 结尾。如果我省略它,我会在标题 1 段落后附加下一段。如果我把它放进去,我最终会将第二段视为标题 1 段。 None 这些行为对我有用。
我的问题是:如何以编程方式更改段落的文本?我认为它必须是可能的,但如果不是,解决方法是什么?我一直想在我想改的那一段之后再新建一段,然后把旧的删掉,但是这样好像不太雅致。
首先,快速回答您提出的问题:如何在保持段落本身完整的情况下替换段落的文本。我无法使用您提供的代码,因为它没有显示您如何得出 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";
背景资料:
您的问题最重要的方面是理解 Word Range
对象。
首先,永远不要依赖 Start
和 End
属性来识别范围。它们适用于 "snapshots",或将一个范围的开始点或结束点动态设置为一秒的开始点或结束点。但是一旦在文档中进行了任何编辑,您就可以将它们丢弃。
当您需要使用范围时,请在 运行 代码期间使用 Range
对象(变量)。
是的,正如您所分析的,Paragraph.Range.Text
确实包含了段落结束标记。这是 ANSI 13,不仅仅是一个马车 return;在幕后,它存储了大量有关段落格式的信息。当您只想处理文本时,将范围缩短一个字符以将段落标记留在范围之外。这可以使用 MoveEnd
方法来完成。