Get all outging connectors from a shape programmatically

I want to rename a connector after a shape has been dropped. Lets say I have a shape1 and I dropped a shape2 connected with shape1. I want the connector shape between shape1 and shape2 so that I can rename it.

1 answer

  • answered 2018-05-16 11:01 JohnGoldsmith

    I guess it depends on what stage you intercept the drop. If it's immediately, you might make some assumptions about how many connectors might be involved, but if if some time after the drop then you might want to determine how many connections are involved.

    As an example, with the following shapes: basic Visio flowchart connectors

    ...you could approach this in a number of ways:

    1. Use the GluedShapes method working back from ShapeTwo
    2. Use the GluedShapes method including the 'from' shape
    3. Iterate through the Connects collection of the Page
    4. Iterate over the Connect objects in on your target shape (ShapeOne)

    I would definitely try and use the GluedShapes method (which came into Visio in 2010) over the Connect objects, but I'm adding them here as they can be useful depending on what you're trying to achieve.

    Here's an example using LINQPad:

    void Main()
    {
        var vApp = MyExtensions.GetRunningVisio();
        var vPag = vApp.ActivePage;
    
        //For demo purposes I'm assuming the following shape IDs
        //but in reality you'd get a reference by other methods
        //such as Window.Selection, Page index or ID 
        var shpOne = vPag.Shapes.ItemFromID[1];
        var shpTwo = vPag.Shapes.ItemFromID[2];
    
        Array gluedIds;
    
        Console.WriteLine("1) using GluedShapes with the 'to' shape only");
        gluedIds = shpTwo.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesIncoming1D,"");
        IterateByIds(vPag, gluedIds);
    
        Console.WriteLine("\n2) using GluedShapes with the 'to' and 'from' shapes");
        gluedIds = shpTwo.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesIncoming1D, "", shpOne);
        IterateByIds(vPag, gluedIds);
    
        Console.WriteLine("\n3) using the Connects collection on Page");
        var pageConns = from c in vPag.Connects.Cast<Visio.Connect>()
                        where c.FromSheet.OneD != 0
                        group c by c.FromSheet into connectPair 
                        where connectPair.Any(p => p.ToSheet.ID == shpOne.ID) && connectPair.Any(p => p.ToSheet.ID == shpTwo.ID)
                        select connectPair.Key.Text;
        pageConns.Dump();
    
    
        Console.WriteLine("\n4) using FromConnects and Linq to navigate from shpOne to shpTwo finding the connector in the middle");
        var shpConns = from c in shpOne.FromConnects.Cast<Visio.Connect>()
                       where c.FromSheet.OneD != 0 
                       let targetConnector = c.FromSheet
                       from c2 in targetConnector.Connects.Cast<Visio.Connect>()
                       where c2.ToSheet.Equals(shpTwo)
                       select targetConnector.Text;
        shpConns.Dump();    
    }
    
    private void IterateByIds(Visio.Page hostPage, Array shpIds)
    {
        if (shpIds.Length > 0)
        {
            for (int i = 0; i < shpIds.Length; i++)
            {
                //Report on the shape text (or change it as required)
                Console.WriteLine(hostPage.Shapes.ItemFromID[(int)shpIds.GetValue(i)].Text);
            }
        }
    }
    

    Running the above will result in this output:

    LINQPad output

    It's worth bearing in mind that the Connects code (3 and 4) makes the assumption that connector shape (1D) are being connected to the flowchart shapes (2D) and not the other way round (which is possible).

    You can think of the connect objects as being analgous to connection points, so in the diagram, the three connector shapes generate six connect objects:

    Visio connect objects

    Anyway, hope that gets you unstuck.

    UPDATE - Just to be clear (and to answer the original question properly), the code to get all outgoing connectors from ShapeOne would be:

    Console.WriteLine("using GluedShapes to report outgoing connectors");
    gluedIds = shpOne.GluedShapes(Visio.VisGluedShapesFlags.visGluedShapesOutgoing1D, "");
    IterateByIds(vPag, gluedIds);