Using the Open Xml SDK, I added a DrawingsPart
to a WorksheetPart
and then later I tried referencing the DrawingsPart
from within the WorksheetPart
but I receive an ArgumentOutOfRangeException
.
Here is the relevant snippet of code:
// Add a new drawings part to the worksheet
var drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
// make a drawing DOM
var drawingRootElement = new WorksheetDrawing();
// add to the drawing DOM
...
// and then...
// associate the drawing DOM to the drawings part
drawingsPart.WorksheetDrawing = drawingRootElement;
// save the drawing DOM back to the drawings part
drawingsPart.WorksheetDrawing.Save();
// and finally...
// here is where it throws the ArgumentOutOfRangeException
// whether I supply the drawingsPart as the argument
// or the value worksheet.DrawingsPart
// it reports the same exception
// I looked up the source of OpenXmlPartContainer.GetIdOfPart
// and it looks like the DrawingsPart is not yet added to the
// PartDictionary of the WorksheetPart. I wonder why?
var relationshipIdOfDrawingsPart = drawingsPart
.GetIdOfPart(worksheetPart.DrawingsPart /* drawingsPart */);
// Create a new drawing element and add it to the Worksheet DOM
var drawingElement = new DocumentFormat.OpenXml.Spreadsheet.Drawing { Id = relationshipIdOfDrawingsPart };
worksheetPart.Worksheet.Append(drawingElement);
Exception details:
System.ArgumentOutOfRangeException occurred HResult=0x80131502
Message=Specified argument was out of the range of valid values.
Source=DocumentFormat.OpenXml StackTrace: at DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer.GetIdOfPart(OpenXmlPart part) at ... my code
I looked up the source of OpenXmlPartContainer.GetIdOfPart
(reproduced below):
// DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer
/// <summary>
/// Gets the relationship ID of the part.
/// </summary>
/// <param name="part">The part.</param>
/// <returns>The relationship ID of the part.</returns>
/// <exception cref="T:System.ArgumentNullException">Thrown when "part" is null reference.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the part does not exist.</exception>
public string GetIdOfPart(OpenXmlPart part)
{
this.ThrowIfObjectDisposed();
if (part == null)
{
throw new ArgumentNullException("part");
}
if (this.PartDictionary.ContainsValue(part))
{
foreach (KeyValuePair<string, OpenXmlPart> current in this.PartDictionary)
{
if (part == current.Value)
{
return current.Key;
}
}
}
throw new ArgumentOutOfRangeException("part");
}
It looks like the DrawingsPart
is not being added to the PartDictionary
of the WorksheetPart
. I wonder why?
Given that worksheetPart.DrawingsPart
and drawingsPart
are the same object, this code does not make sense:
// and finally...
// here is where it throws the ArgumentOutOfRangeException
// whether I supply the drawingsPart as the argument
// or the value worksheet.DrawingsPart
// it reports the same exception
// I looked up the source of OpenXmlPartContainer.GetIdOfPart
// and it looks like the DrawingsPart is not yet added to the
// PartDictionary of the WorksheetPart. I wonder why?
var relationshipIdOfDrawingsPart = drawingsPart
.GetIdOfPart(worksheetPart.DrawingsPart /* drawingsPart */);
since that would only work if the object's PartDictionary
contained a reference to itself.
As such, you need to instead call GetIdOfPart
on the parent object, not drawingsPart
itself.
User contributions licensed under CC BY-SA 3.0