If you haven’t already seen this, get over to Donovan Lange’s blog. Donovan, Omar, and David have put together an abstracted managed assembly that provides an object model for the SimpleImport functionality OneNote added for SP1. That’s right; you don’t even have to create the XML for the import yourself. The OneNote guys have you covered.
I’m currently putting together an article that highlights this class library and all the functionality it provides. I’ve been pouring over the code for the last week or so, and I think I’ve finally got it. (The assembly itself is written in C#. Did I mention I’m about as fluent in C# as in ancient Armenian?) I have to say, this is some very well-thought-out work.
The OneNote guys have included detailed technical documentation in the download itself, but I thought it might be worth taking a few minutes and putting together a high-level overview of how the classes work. So if you just want to get up and running, and aren’t too concerned about how the assembly does what it does so well, then read on.
They’ve really made the class library easy to use. Here’s all you need to do:
Create a new Page object
Not much to say here. Once you’ve created the page, you can set its attributes using various properties such as Date, PreviousPage, RTL, SectionPath, and Title. The PreviousPage property sets the value of the ‘InsertAfter’ XML attribute; the others are pretty self-explanatory.
Create the content you want to add to your new page
There are three types of objects you can add to a page: ImageObject, InkObject, or OutlineObject objects. All page objects share common properties, such as Height, Width, and Position.
Note While the OutlineObject inherits the Height property from its base class for consistency, outlines cannot have an explicitly specified height. Therefore, accessing or modifying the Height property of an OutlineObject will result in an error.
Each ImageObject and InkObject contains data representing the actual image or ink content you want to add to the page. You get and set this data by using the ImageData and InkData properties, respectively.
You use these properties to get or set a BinaryData or FileData object. The BinaryData class represents raw binary data in memory. When you add an ImageObject or InkObject object containing BinaryData to a page, the OneNote Import Managed Assembly ensures this data is properly base-64 encoded. The FileData class represents data that is stored in an external file, and is marshaled to OneNote as a file path.
For the most part, you’ll really only need to create BinaryData and FileData objects directly when you want to update existing image or ink objects. The ImageObject and InkObject each provide convenience constructors that create the appropriate data object, when passed a System.IO.FileInfo object or binary array of bytes as a method parameter.
OutlineObject objects are slightly more complex because outlines can be comprised of ImageContent, InkContent and HtmlContent objects. Add content to an OutlineObject using the AddContent method. Outline content objects are displayed within the outline in the same order in which they are added to the OutlineObject object.
The ImageContent and InkContent classes are very similar to the ImageObject and InkObject classes. Again, the actual image or ink content is represented by either a BinaryData or FileData object. This object is also created based on the specified argument passed to the ImageContent or InkContent constructor, and you can subsequently access it using the ImageData or InkData property, respectively. Note that neither the ImageContent or InkContent classes contain properties for setting their position and size on the page, as these properties are set for the outline as a whole.
The HtmlContent object also contains data within the HtmlData property, except it’s data is represented as either a FileData or StringData object. The StringData object represent string data as a System.String. Constructors on the HtmlContent object enable you to create a new HtmlContent object based off of pre-existing HTML in a string object or a FileInfo object containing the path to an HTML file.
Add objects to the page
Add the objects you’ve created to the Page object using the AddObject method. You can add as many as you want, in any order. How the objects are arranged on the page depends on the coordinates specified in the Position child object for each ImageObject, InkObject, or OutlineObject.
Import the page
Now that you’ve got your page set up with all your content, it’s time to import it into OneNote. You do this using the Page.Commit method. This method does several vital things, including:
· Creates the XML document to be used for the OneNote SimpleImport class.
· Specifies the correct OneNote namespace, based on whether the OneNote SP1 Preview or SP1 release version is installed on the current machine. (Now, how thoughtful is that?)
· Adds an <EnsurePage> element for the page, using the Page object properties you’ve set.
· If your page contains objects, then the method also creates a <PlaceObjects> element to insert, edit, or delete those objects as specified.
· Serializes the page and all its contents to XML, and adds them to the XML import document. In the course of this, it also does some minor checking of any HTML content to format it property for OneNote.
· Validates the XML it created, to make sure OneNote accepts it.
· Calls the SimpleImporter class and imports the content into OneNote.
Pretty slick, no?
Here’s some things to keep in mind:
The OneNote classes internally generate the necessary GUIDs that OneNote needs to identify each object and page. You cannot access a page or object’s GUID from outside the OneNote class assembly. The GUIDs do appear in the XML passed to the SimpleImporter.Import method, of course.
On a sidenote, Donovan tells me he intends to change this. Originally, the intent was to hide the GUIDs for the benefit of new users. But it turns out that many scenerios require control over the Page and PageObject GUIDs. If you do need access to these GUIDs, here’s two strategies to consider:
· Override the class, and make the GUID properties publicly accessible.
· Serialize and persist the Page object between sessions, and then deserialize it as necessary.
Page objects keep track of whether they have been committed (or in other words, imported) and, additionally, keep track of modifications that require an update (that is, another import). So, after you commit a Page for the first time, if you then immediately call the Commit method again, none of the original objects would be re-imported. However, suppose that, after you commit a page, you then added new objects to that page, or changed the content or properties of an existing object on the page. In that case those new or modified objects will be re-imported the next time you execute the Commit method.
The OneNote SimpleImport API does not permit you to change a page’s date, title, insertAfter, or RTL attributes once you’ve imported the page. Because of this, once you’ve called the Commit method for a Page object, the following Page properties become read-only and throw an exception if you try and set them: Date, PreviousPage, RTL, and Title.
You can delete an object from a page using the Page.DeleteObject method. Much like the Page.AddObject method, the deletion does not in fact occur until you execute the Commit method; only then is it deleted within OneNote and removed as a child of the Page object.
Next time, I’ll include an example and we’ll take a look at the XML actually produced.