Note: Cross posted from Coding The Document.
Sometimes in order to work with Open XML we need a little help from other tools. In this post I am going to describe a fairly simple solution for marking up PowerPoint presentations so that they can be used as templates and processed using the Open XML SDK.
Add-ins are tools which it can be hard to find information on. I am going to up the obscurity by adding a Ribbon button. For my example I am using Visual Studio 2008 and creating a PowerPoint 2007 Add-in project. To that add a Ribbon Visual Designer. The new ribbon by default will show up on the Add-in tab.
Add a button to the ribbon. Also add a WinForm to collect a new name for the object selected. Make sure to set the OK button’s DialogResult to OK. In the ribbon button click event add the following code.
ObjectNameForm dialog = new ObjectNameForm();
Selection selection = Globals.ThisAddIn.Application.ActiveWindow.Selection;
dialog.objectName = selection.ShapeRange.Name;
if (dialog.ShowDialog() == DialogResult.OK)
selection.ShapeRange.Name = dialog.objectName;
This code will first read the current Name attribute of the Shape object. If the user clicks OK on the dialog it save the string value back to the same place.
Once it is done you can retrieve identify the control through Open XML via the NonVisualDisplayProperties objects. The only problem is that this object is a child of several different classes. This means that there isn’t just one way to retrieve the value. Below are a couple of pieces of code to identify the container that you have named.
The first example is if you are naming placeholders in a layout slide.
foreach(var slideMasterPart in slideMasterParts)
var layoutParts = slideMasterPart.SlideLayoutParts;
foreach(SlideLayoutPart slideLayoutPart in layoutParts)
foreach (assmPresentation.Shape shape in slideLayoutPart.SlideLayout.CommonSlideData.ShapeTree.Descendants<assmPresentation.Shape>())
var slideMasterProperties =
from p in shape.Descendants<assmPresentation.NonVisualDrawingProperties>()
where p.Name == TokenText.Text
if (slideMasterProperties.Count() > 0)
tokenFound = true;
The second example allows you to find charts that you have named with the add-in.
foreach(var slidePart in slideParts)
foreach(assmPresentation.Shape slideShape in slidePart.Slide.CommonSlideData.ShapeTree.Descendants<assmPresentation.Shape>())
var slideProperties = from g in slidePart.Slide.Descendants<GraphicFrame>()
where g.NonVisualGraphicFrameProperties.NonVisualDrawingProperties.Name == TokenText.Text
if(slideProperties.Count() > 0)
tokenFound = true;
Together the combination of Open XML and VSTO add-ins make a powerful combination in creating a process for maintaining a template and generating documents from the template.