7

I have the following task. I'm writing an Add-In for Visio 2010 on C# in Studio 2010. Let's say that I have a diagram opened. And I have a shape of any kind in this diagram (let's try to manage one shape for the begining). The question is how can I read any properties of this shape? Which API should I use?

Basic algorithm:

  1. Scan opened document for shapes
  2. If there are any shapes in document, then return an array (or a list) of all shapes (null is returned in case of no shapes in current document)
  3. Run over shapes array and read any property for each element (that would be great to have a chance to write/modify property)

(Code example would be greatly appreciated)

ib.
  • 25,324
  • 10
  • 71
  • 97
Daniil Belonin
  • 355
  • 1
  • 9
  • 19

3 Answers3

8

I assume that by properties you are referring to Shape Data, which used to be called Custom Properties in the UI and is still know by that name in the API.

If you are not familiar with the ShapeSheet you should have look at a shape with custom properties in the ShapeSheet first to see how the properties are defined. See "What happened to the ShapeSheet?" to learn how to open the Shapesheet in Visio 2010.

The following example program should get you started. This example assumes that you have the Visio Primary Interop Assembly installed on you PC and that you have included a referee to Microsoft.Office.Interop.Visio in your project.

namespace VisioEventsExample
{
    using System;
    using Microsoft.Office.Interop.Visio;

    class Program
    {
        public static void Main(string[] args)
        {
            // Open up one of Visio's sample drawings.
            Application app = new Application();
            Document doc = app.Documents.Open(
                @"C:\Program Files\Microsoft Office\Office14\visio content\1033\ASTMGT_U.VST");

            // Get the first page in the sample drawing.
            Page page = doc.Pages[1];

            // Start with the collection of shapes on the page and 
            // print the properties we find,
            printProperties(page.Shapes);
        }

        /* This function will travel recursively through a collection of 
         * shapes and print the custom properties in each shape. 
         * 
         * The reason I don't simply look at the shapes in Page.Shapes is 
         * that when you use the Group command the shapes you group become 
         * child shapes of the group shape and are no longer one of the 
         * items in Page.Shapes.
         * 
         * This function will not recursive into shapes which have a Master. 
         * This means that shapes which were created by dropping from stencils 
         * will have their properties printed but properties of child shapes 
         * inside them will be ignored. I do this because such properties are 
         * not typically shown to the user and are often used to implement 
         * features of the shapes such as data graphics.
         * 
         * An alternative halting condition for the recursion which may be 
         * sensible for many drawing types would be to stop when you 
         * find a shape with custom properties.
         */
        public static void printProperties(Shapes shapes)
        {
            // Look at each shape in the collection.
            foreach (Shape shape in shapes)
            {               
                // Use this index to look at each row in the properties 
                // section.
                short iRow = (short) VisRowIndices.visRowFirst;

                // While there are stil rows to look at.
                while (shape.get_CellsSRCExists(
                    (short) VisSectionIndices.visSectionProp, 
                    iRow, 
                    (short) VisCellIndices.visCustPropsValue,
                    (short) 0) != 0)
                {
                    // Get the label and value of the current property.
                    string label = shape.get_CellsSRC(
                            (short) VisSectionIndices.visSectionProp, 
                            iRow,
                            (short) VisCellIndices.visCustPropsLabel
                        ).get_ResultStr(VisUnitCodes.visNoCast);

                    string value = shape.get_CellsSRC(
                            (short) VisSectionIndices.visSectionProp, 
                            iRow,
                            (short) VisCellIndices.visCustPropsValue
                        ).get_ResultStr(VisUnitCodes.visNoCast);

                    // Print the results.
                    Console.WriteLine(string.Format(
                        "Shape={0} Label={1} Value={2}",
                        shape.Name, label, value));

                    // Move to the next row in the properties section.
                    iRow++;
                }

                // Now look at child shapes in the collection.
                if (shape.Master == null && shape.Shapes.Count > 0)
                    printProperties(shape.Shapes);
            }
        }
    }
}
  • Hello Pat Thank you for your detailed answer. That gave me some ideas. I managed to proceed with my task with your help and several books. I plan to work closely with Visio for the following month or two. May I add you to my contacts in LinkedIn as I may be need your help and advice? (I have sent an invitation) Thanks again. Dan – Daniil Belonin Jun 09 '11 at 04:11
  • Daniil, If you have software development related questions please ask them on Stack Overflow. If you need to contact me privately please use my email address in my profile. - Pat –  Jun 09 '11 at 15:15
4

I wrote a library that makes this a easier

To retrieve the properties for multiple shapes:

var shapes = new[] {s1, s2};
var props = VA.CustomProperties.CustomPropertyHelper.GetCustomProperties(page, shapes);

The return value stored in props will be a list of dictionaries. Each dictionary corresponds to the properties of the specified shapes. The names of the properties are the keys in the dictionary.

To get the "Foo" property for the first shape...

props[0]["Foo"] 

which retrieves an object which contains the Formulas & Results for these aspects of a property:

  • Calendar
  • Format
  • Invisible
  • Label
  • LangId
  • Prompt
  • SortKey
  • Type
  • Value
  • Verify
saveenr
  • 7,249
  • 3
  • 17
  • 19
0

To all those, who will need code help later on this question:

...
using Visio = Microsoft.Office.Interop.Visio;

namespace RibbonCustomization
{
   [ComVisible(true)]
   public class Ribbon1 : Office.IRibbonExtensibility
   {

      public void ReadShapes(Microsoft.Office.Core.IRibbonControl control)
      {
         ExportElement exportElement;
         ArrayList exportElements = new ArrayList();

         Visio.Document currentDocument = Globals.ThisAddIn.Application.ActiveDocument;
         Visio.Pages Pages = currentDocument.Pages;
         Visio.Shapes Shapes;

         foreach(Visio.Page Page in Pages)
         {
            Shapes = Page.Shapes;
            foreach (Visio.Shape Shape in Shapes)
            {
               exportElement = new ExportElement();
               exportElement.Name = Shape.Master.NameU;
               exportElement.ID = Shape.ID;               
               exportElement.Text = Shape.Text;
               ...
               // and any other properties you'd like

               exportElements.Add(exportElement);
            }
         }
....
DarthJDG
  • 16,140
  • 11
  • 47
  • 55
Daniil Belonin
  • 355
  • 1
  • 9
  • 19