Open XML document ContentControls problem with signed id's
I have an application that generates Open XML documents with Content Controls.
To create a new Content Control I use Interop and the method ContentControls.Add
. This method returns an instance of the added Content Control.
I have some logic that saves the id of the Content Control to reference it later, but in some computers I've been having a weird problem.
When I access the ID property of the Content Control I just created, it returns a string with the numeric id, the problem is that when this value is too big, after I save the document, if I look through the document.xml in the generated document, t开发者_如何学Che <w:id/>
element of the <w:sdtPr/>
element has a negative value, that is the signed equivalent of the value I got from the Id
property of the generated control.
For example:
var contentControl = ContentControls.Add(...);
var contentControlId = contentControl.ID;
// the value of contentControlId is "3440157266"
If I save the document and open it in the Package Explorer, the Id
of the Content Control is "-854810030" instead of "3440157266".
What have I figured out is this:
((int)uint.Parse("3440157266")).ToString() returns "-854810030"
Any idea of why this happens? This issue is hard to replicate because I don't control the Id
of the generated controls, the Id
is automatically generated by the Interop libraries.
When displayed in 32-bit binary format, -854810030 and 3440157266 are just the same!
This problem is mentioned in the MSDN documentation of the ContentControl.ID Property:
When you get the ID property value at runtime, it is returned as an unsigned value. However, when saved into the Office Open XML file format, it is saved as a signed value. If your solution attempts to map programmatically returned values to values saved in the file format, you must check for both the unsigned and signed version of the value obtained from this property.
As Claude Martel mentioned, -854810030 and 3440157266 are ident. You can easily check this by casting the signed Int32
to a unsigned UInt32
:
var id = Convert.ToInt32("-854810030 ");
UInt32 uId = (uint) id;
Assert.AreEqual(3440157266, uId);
I've had the very same type of issue in the past. The ID is unreliable as it doesn't seem to perpeturate. What I did instead is stored a name of the Content Control's .Tag
so I could access it later.
精彩评论