【问题标题】:Open XML document ContentControls problem with signed id's打开带有签名 ID 的 XML 文档 ContentControls 问题
【发布时间】:2026-01-05 06:35:01
【问题描述】:

我有一个使用内容控件生成 Open XML 文档的应用程序。

要创建一个新的内容控件,我使用 Interop 和方法 ContentControls.Add。此方法返回添加的内容控件的实例。

我有一些逻辑可以保存内容控件的 id 以供以后引用,但在某些计算机上我遇到了一个奇怪的问题。

当我访问刚刚创建的内容控件的ID属性时,它返回一个带有数字id的字符串,问题是当这个值太大时,我保存文档后,如果我查看document.xml 在生成的文档中,<w:sdtPr/> 元素的<w:id/> 元素有一个负值,即我从生成控件的Id 属性中得到的值的有符号等效值。

例如:

var contentControl = ContentControls.Add(...);
var contentControlId = contentControl.ID;
// the value of contentControlId is "3440157266"

如果我保存文档并在包资源管理器中打开它,内容控件的Id 是“-854810030”而不是“3440157266”。

我发现是这样的:

((int)uint.Parse("3440157266")).ToString()  returns "-854810030"

知道为什么会这样吗?这个问题很难复制,因为我不控制生成控件的IdId 是由 Interop 库自动生成的。

【问题讨论】:

    标签: ms-word interop openxml word-contentcontrol


    【解决方案1】:

    当以 32 位二进制格式显示时,-854810030 和 3440157266 是一样的!

    【讨论】:

      【解决方案2】:

      MSDN documentation of the ContentControl.ID Property 中提到了这个问题

      当您在运行时获取 ID 属性值时,它会作为无符号值返回。但是,当保存为 Office Open XML 文件格式时,它会保存为带符号的值。如果您的解决方案尝试将编程返回的值映射到以文件格式保存的值,则必须检查从该属性获得的值的无符号和有符号版本。

      正如 Claude Martel 所说,-854810030 和 3440157266 是相同的。您可以通过将已签名的 Int32 转换为未签名的 UInt32 来轻松检查这一点:

      var id = Convert.ToInt32("-854810030 ");
      UInt32 uId = (uint) id;
      
      Assert.AreEqual(3440157266, uId);
      

      【讨论】:

        【解决方案3】:

        我过去也遇到过同样类型的问题。 ID 是不可靠的,因为它似乎不会永久存在。我所做的是存储内容控件的名称.Tag,以便我以后可以访问它。

        【讨论】:

          最近更新 更多