PowerShell and Visio Part 6 – Containers

Ok…I think this is the last of the “how to perform primitive operations in Visio” articles that I’m going to do.  Hope you’ve been enjoying them.  If you haven’t been keeping up, you can find them all here.

In this installment, I’m going to show you how to create a container in Visio.  Containers are really useful, because when you move them, you move the contents as well.  Along with connections, containers are probably the most important feature of Visio (at least for me).

Container Basics

The first thing to know is that containers are special kinds of shapes, just like the ones we used when we were dropping shapes on the page.  So if you have containers in a stencil you’re using, then you can use those.  If you don’t have any special containers you can use the built-in container stencil that you see in Visio when you go to insert a container from the ribbon:

insertContainerStencil

To use the built-in stencil, though, you have to know where to find it. Fortunately, you can ask Visio where to find it. If you have a reference to Visio in a variable (we’ve been using $Visio), you do it something like this:

$stencilPath=$Visio.GetBuiltInStencilFile(2,0)

The 2 represents the constant visBuiltinStencilContainers, and 0 is visMSDefault, meaning to use the default measurement units. If you’ve been reading along, you have already seen a bunch of constants. There are tons more, and I’ll let you in on how I’m making them a bit easier to deal with in the next post.

Once we have that stencil path, we can use the OpenEx method on the Documents collection to open the stencil (hidden, of course):

$stencil=$Visio.Documents.OpenEx($stencilPath,64)

That stencil has a bunch of masters on it:
containerMasters

There are a couple of approaches to adding a container to a document:

  1. Drop the container as a shape, and then add shapes to it.
  2. Drop the container as a container, listing the shapes that are in it.

Dropping containers as shapes

For the first option, you already know how to add a shape to a page using the Drop() method.

$page=$Visio.ActivePage
$container=$page.Drop($master,5,5)

droppedContainer

After you do that, you use the ContainerProperties property of the container (which is a special property other shapes don’t have), calling the AddMember() method to add shapes. You can also add Selection objects, but we haven’t talked about those.

Let’s draw a rectangle on the page (it’s quicker to show than a custom shape, but it works the same):

 $rec=$page.DrawRectangle(2,3,5,6)
 $container.ContainerProperties.AddMember($rec,1)

And we can see that the rectangle is inside the container. We passed a 1 to tell the container to resize to fit the shape we put in it. If you don’t do that, you will probably have shapes hanging over the edges of the container.

If you have more shapes you want in the container, you can add them as well by calling AddMember. Not very tricky.

The problem I have with this approach is that you have to know where to drop the container in the first place. Not a huge deal, but the less I have to know the better.

Dropping Containers around shapes

To use the second approach, you need to start by dropping the shapes that you want inside the container onto the page. Again, I’ll just drop a rectangle, but the idea is the same with any shapes. Once I’ve got the shape, I use the DropContainer method on the page to drop the new master shape (of the container) and tell it the shape I want it to contain.

 $rec=$page.DrawRectangle(2,3,5,6)
 $container=$page.DropContainer($master,$rec)

DropContainer_2

If you compare the output of the two approaches, you’ll see that the second give a “tighter” container, that is, since we didn’t tell Visio where to place the container, it calculated exactly how big it needed to be and where to put it.

Adding More Shapes

 
Now that you have a container you can loop through other shapes that need to be in it and use the ContainerProperties.AddMember method to add all of them (in a loop!). No need to bore you with the details. You’re sharp and can figure that out.

Let me know what you think

–Mike

P.S. If you want to add all of the shapes at once (with either method) you can use a Selection object. They’re not hard to use, but I wanted to keep this post focused on containers.