My Latest enhancements to the VisioAutoExt library
I've published a big update to the VisioAutoExt library on Codeplex. The changes are significant enough with enough breaking changes from the old code that I'm calling this version 3.0.
Three things I'll talk about in this post:
- What changed
- Why it's interesting to use the library
- How to use the library
What changed
- UPDATES: Lots of renaming and refactoring
- NEW: Added a DemoVisioAutomation winform application. It makes it easer to see what can be done with the library
- NEW: Enhanced Batching support via BatchFormulaApplier
- UPDATES: Lots of the test cases now use the Batching support and so drawing takes place much faster.
- NEW: An experimental library called VisDOM added to support even simpler and faster drawing in batch and perhaps one day emit Visio XML directly without launching the app
- UPDATE: Kuler demo updated to latest XML schema, added test cases
- NEW: VisioHelper a winform app that helps in drawing nice gradients in visio
- NEW: VisProps, a class that contains predefined section,row,and cell tuples. Makes using CellsSRC much easier
Why use it?
This is best illustrated by walking through a simple project (create a new doc and draw a rectangle programmatically).
The desired result
The output we want is simple:
Step 1: Starting point: let's do this without the VisioAutoExt library
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IVisio = Microsoft.Office.Interop.Visio;
using VisioAutomation;
namespace VisioAutomationSamples
{
public partial class Demo
{
public static void sample1_a()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add("");
IVisio.Page page = doc.Pages[1];
page.PageSheet.get_CellsSRC(
(short)IVisio.VisSectionIndices.visSectionObject,
(short)IVisio.VisRowIndices.visRowPage,
(short)IVisio.VisCellIndices.visPageWidth).Formula = "5";
page.PageSheet.get_CellsSRC(
(short)IVisio.VisSectionIndices.visSectionObject,
(short)IVisio.VisRowIndices.visRowPage,
(short)IVisio.VisCellIndices.visPageHeight).Formula = "5";
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
}
}
The first improvement: No longer need to use the awkward "get_CellsSRC", now it's just CellsSRC
This makes it look much more like VB code that Visio emits when it records Macros. So that's an easy, cheap win.
public static void sample1_b()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add("");
IVisio.Page page = doc.Pages[1];
page.PageSheet.CellsSRC(
(short)IVisio.VisSectionIndices.visSectionObject,
(short)IVisio.VisRowIndices.visRowPage,
(short)IVisio.VisCellIndices.visPageWidth).Formula = "5";
page.PageSheet.get_CellsSRC(
(short)IVisio.VisSectionIndices.visSectionObject,
(short)IVisio.VisRowIndices.visRowPage,
(short)IVisio.VisCellIndices.visPageHeight).Formula = "5";
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
The second improvement: No more casting to "short" with CellsSRC
Enums such as VisSectionIndices are ints. But CellSRC accepts shorts and this results in code always casting these values to type short. Now that is no longer necessary. And again this looks more like the code that Visio generates for macros. Another easy, cheap, win.
public static void sample1_c()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add("");
IVisio.Page page = doc.Pages[1];
page.PageSheet.CellsSRC(
IVisio.VisSectionIndices.visSectionObject,
IVisio.VisRowIndices.visRowPage,
IVisio.VisCellIndices.visPageWidth).Formula = "5";
page.PageSheet.CellsSRC(
IVisio.VisSectionIndices.visSectionObject,
IVisio.VisRowIndices.visRowPage,
IVisio.VisCellIndices.visPageHeight).Formula = "5";
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
The third improvement: Much less typing and memory required to use CellsSRC
The problem with CellsSRC is that you always need three parameters and have get them correct. This has gotten much simpler in v3. The CellsSRC now takes an object that bundles all three together and a predefined list of these is available under the VisProps class.
So instead of remembering
IVisio.VisSectionIndices.visSectionObject, IVisio.VisRowIndices.visRowPage, IVisio.VisCellIndices.visPageWidth
You now just have to remember:
VisProps.PageWidth
And so the code gets much shorter.
public static void sample1_d()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add("");
IVisio.Page page = doc.Pages[1];
page.PageSheet.CellsSRC( VisProps.PageWidth ).Formula = "5";
page.PageSheet.CellsSRC( VisProps.PageHeight ).Formula = "5";
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
The fourth improvement: Convenience. Common tasks are easy available.
Extension methods have been added Visio classes that "just work". See how easy it is to set the page size?
public static void sample1_e()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add("");
IVisio.Page page = doc.Pages[1];
page.SetSize(5, 5);
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
More convenience ...
You can just create the page with the correct size in the first place.
public static void sample1_f()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add( new Isotope.Drawing.Size(5,5) );
IVisio.Page page = doc.Pages[1];
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
The Diff
Red is what was removed. Light red means a removal occurred on that line.
Yellow is what was added. Light yellow means an addition occurred on that line.
How to start using the Library
Step 1- Create a new project in Visual Studio 2008 , Make sure to select .NET Framework 3.5
Step 2 - Add a reference to VIsio 2007 Primary Interop Assembly
Right-click on <project> / References then select Add Reference
Select Microsoft.Office.Interop.Visio. Make sure you select Version 12, not 11
It will show in the references ...
Step 3 -Alias "IVisio" to Microsoft.Office.Interop.Visio
Add this line to the top part of the file "using IVisio = Microsoft.Office.Interop.Visio;"
Step 4. Add a reference to Isotope.Drawing.DLl and Isotope.Common.DLl, VisioAutomation.DLL
You'll see them in the references
Step 5. add using VisioAutomation
To use it effectively you must have a "using VisioAutomation" because that is how the extension methods get bound.
Let's compare, look at what Intellisense shows on Shape if you do not add this using line...
See After SetCenter there are just three methods before you see the ShapeAdded event.

Now when you add "using VisioAutomation" you'll see a all the extension methods are available.
The Extension methods are clearly marked with the downward blue arrow
Now try it out...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IVisio = Microsoft.Office.Interop.Visio;
using VisioAutomation;
public class Demo
{
public static void sample1_f()
{
IVisio.Application visapp = new Microsoft.Office.Interop.Visio.ApplicationClass();
IVisio.Document doc = visapp.Documents.Add( new Isotope.Drawing.Size(5,5) );
IVisio.Page page = doc.Pages[1];
IVisio.Shape shape1 = page.DrawRectangle(1, 1, 2, 2);
}
}
Reference: Here's what VisProps contains
