3

目前,我正在使用 VSTO,更准确地说是使用 C# 和“Microsoft Word”应用程序插件。我确实想以编程方式创建嵌套字段。我提出了以下源代码(用于测试目的):

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, EventArgs e)
    {
        // TODO This is just a test.
        this.AddDocPropertyFieldWithinInsertTextField("Author", ".\\\\FileName.docx");
    }

    private void AddDocPropertyFieldWithinInsertTextField(string propertyName, string filePath)
    {
        // TODO Horrible, since we rely on the UI state.
        this.Application.ActiveWindow.View.ShowFieldCodes = true;

        Word.Selection currentSelection = this.Application.ActiveWindow.Selection;

        // Add a new DocProperty field at the current selection.
        currentSelection.Fields.Add(
            Range: currentSelection.Range,
            Type: Word.WdFieldType.wdFieldDocProperty,
            Text: propertyName,
            PreserveFormatting: false
        );

        // TODO The following fails if a DocProperty with the specified name does not exist.

        // Select the previously inserted field.
        // TODO This is horrible!
        currentSelection.MoveLeft(
            Unit: Word.WdUnits.wdWord,
            Count: 1,
            Extend: Word.WdMovementType.wdExtend
        );

        // Create a new (empty) field AROUND the DocProperty field.
        // After that, the DocProperty field is nested INSIDE the empty field.
        // TODO Horrible again!
        currentSelection.Fields.Add(
            currentSelection.Range,
            Word.WdFieldType.wdFieldEmpty,
            PreserveFormatting: false
        );

        // Insert text BEFORE the inner field.
        // TODO Horror continues.
        currentSelection.InsertAfter("INCLUDETEXT \"");

        // Move the selection AFTER the inner field.
        // TODO See above.
        currentSelection.MoveRight(
            Unit: Word.WdUnits.wdWord,
            Count: 1,
            Extend: Word.WdMovementType.wdExtend
        );

        // Insert text AFTER the nested field.
        // TODO See above.
        currentSelection.InsertAfter("\\\\" + filePath + "\"");

        // TODO See above.
        this.Application.ActiveWindow.View.ShowFieldCodes = false;

        // Update the fields.
        currentSelection.Fields.Update();
    }

虽然提供的代码涵盖了需求,但它存在一些主要问题(如果阅读一些代码注释,您可以看到),例如:

  1. 它并不健壮,因为它依赖于应用程序的 UI 状态。
  2. 是冗长的。任务并不复杂,imo。
  3. 这不容易理解(重构可能会有所帮助,但通过解决问题 1. 和 2.,这个缺点应该会消失)。

我对万维网做了一些研究,但还没有找到一个干净的解决方案。

所以,我的问题是:

  • 有人可以提供(替代)C# 源代码,它比我的更强大,并且允许我将嵌套字段添加到“Microsoft Word”文档中吗?
4

1 回答 1

1

I've created a generic implementation to create both non-nested and nested fields with VSTO for Microsoft Word. You can see the relevant source code in this Gist. I've ported the VBA source code from the article Nested Fields in VBA to C# and applied some improvements.

Still not perfect (needs some additional error handling), but far better than a solution with a Selection object, which relies on the state of the user interface!

于 2013-08-17T14:51:20.270 回答