Shape text linebreaks causes connection to be lost (C#)

Started by Nostalgia, January 09, 2019, 12:03:56 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Nostalgia

Hi there! I recently got an idea, which gave me the oppertunity to learn how to program Visio files from C#. This, however, has left me with a problem which I cannot seem to solve.

So right now I am creating "Class"-shapes from the UML class stencils, where there is a container with boxes (shapes?) inside (one for the class, one for fields (and a separator here) and one for methods). However, when I try to write some text to it, and make a line break (either through \n or (char)10), the box gets disconnected from the original container, causing the layout to be messed up. For a visual image of how this looks, please take a look at the attached image (left side is what I "want", right side is what happens).

Now the way that I try and do this, is by doing the following code:


                //Drop the shape from the stencils
                Shape visioClassShape = visioPage.Drop(visioRectMaster, i * 3, 10);

                //Gets all shape ID's within the newly created shape
                var ids = visioClassShape.ContainerProperties.GetMemberShapes((int)VisContainerFlags.visContainerFlagsDefault);

                foreach (int id in ids)
                {

                    //Get the specific shape from the page
                    Shape shape = visioPage.Shapes.ItemFromID[id];

                   //Try and set the shape text
                    shape.Text = " Test " + (char)10;
                    shape.Text += " TestLineTwo" + (char)10;
                   }



I have also read that (char)13 should be used, but if that is used instead of (char)10. But if I use (char)13 alone, no line break occurs, and if I use both, the original result happens again.
I apologize if any information is lacking, but I would be grateful if anyone can give me some hints about how to either do it properly, or how to fix it!

Side note: I work in Visio 2016, if that matters!

Thanks in advance!

wapperdude

#1
Sorry, don't no C# from D flat... :o  Generally, the preferred method is using "characters", but in VBA, either of the following two macros will work.

Note, the shape ID is hardcoded.  In my test case, I had two rectangles, sheet.1 and sheet.2.  Both rectangles are included in a single container.

HTH
Wapperdude


Sub CatNRpl()
    Dim shpChrs4 As Visio.Characters
   
    shpChrs1 = "Line 1"
    shpChrs2 = "Line 2"
    Set shpChrs4 = ActiveWindow.Page.Shapes.ItemFromID(1).Characters
   
    shpChrs4 = shpChrs1 & Chr(10) & shpChrs2
       
End Sub
Sub CatTry2()
Dim vsoShp As Visio.Shape

Set vsoShp = ActivePage.Shapes.ItemFromID(2)

vsoShp.Text = "Line One" & Chr(10)
vsoShp.Text = vsoShp.Text & "Line Two"


End Sub

Visio 2019 Pro

Paul Herber

Not sure what you mean by "the box gets disconnected". Is the box still part of the container?

You could remove the "+(char)10" from the 2nd line of text.
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

Nostalgia

Quote from: Paul Herber on January 09, 2019, 10:08:24 AM
Not sure what you mean by "the box gets disconnected". Is the box still part of the container?

You could remove the "+(char)10" from the 2nd line of text.
That's the thing, I don't think it's part of the container anymore. If I move it outside of the container nothings happens, but if I drag it into where it should be (like the -memberName box, but above the separator), it snaps into place and fixes itself. If I move the -memberName box instead though (without using any of my code), I can see that the original container automatically gets smaller. I don't know if I'm allowed to post links to gifs, but here is one: https://gyazo.com/938e1214cb462d38a11b4a819a291202. Very sorry if this is not allowed!

And to WapperDude; Thank you for taking your time to write some code. From what I can "translate" from VBA to C#, what you are suggesting is exactly what I am doing (Except for the fact that you get "Set shpChrs4 = ActiveWindow.Page.Shapes.ItemFromID(1).Characters" and then set it's value after. When I do that I get an error saying that Characters is read-only?)

Paul Herber

If you think the box is no longer part of the container then you could try running your code again but with the text changed slighly, if the text doesn't update then the box is no longer in the container. Or just try dragging the container and see what moves.

Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

Nostalgia

Quote from: Paul Herber on January 09, 2019, 11:03:11 AM
If you think the box is no longer part of the container then you could try running your code again but with the text changed slighly, if the text doesn't update then the box is no longer in the container. Or just try dragging the container and see what moves.
I did the "dragging-test", and sure enough, the box with text doesn't follow it. How would I go about connecting it to the container again, if you know?
-Also, thank you for taking your time to help me!

Paul Herber

It shouldn't have become disconnected in the first place!
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

Nostalgia

That is of course true! I suspect it's due to the container not being one that I've made myself, but a premade one from the UML stencil. It has a bunch of "restrictions" (like you can't scale it yourself and things like that), so maybe there is a restriction that causes shapes to disconnect if tampered with from the outside.

Paul Herber

The UML container shapes do have some special attributes, extra menu options are visible that are not normally available. So there is something different about them. Best to use a normal container shape.
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

Croc

You can try to force the shape back into the container.
Like that:
Dim pg As Visio.Page
Dim shp As Visio.Shape, shp0 As Visio.Shape
Sub Macro1()
    Set pg = ActivePage
    Set shp = pg.Drop(Documents.Item("USTRME_M.VSSX").Masters.ItemU("Class"), 2, 6)
    Macro2
End Sub
Sub Macro2()
    ids = shp.ContainerProperties.GetMemberShapes(0)
    For i = 0 To UBound(ids)
        Set shp0 = pg.Shapes.ItemFromID(ids(i))
        shp0.Text = shp0.Text & Chr(10) & shp0.Text
        shp.ContainerProperties.InsertListMember shp0, i + 1
    Next
End Sub

Nostalgia

Quote from: Croc on January 09, 2019, 01:15:32 PM
You can try to force the shape back into the container.
Like that:
Dim pg As Visio.Page
Dim shp As Visio.Shape, shp0 As Visio.Shape
Sub Macro1()
    Set pg = ActivePage
    Set shp = pg.Drop(Documents.Item("USTRME_M.VSSX").Masters.ItemU("Class"), 2, 6)
    Macro2
End Sub
Sub Macro2()
    ids = shp.ContainerProperties.GetMemberShapes(0)
    For i = 0 To UBound(ids)
        Set shp0 = pg.Shapes.ItemFromID(ids(i))
        shp0.Text = shp0.Text & Chr(10) & shp0.Text
        shp.ContainerProperties.InsertListMember shp0, i + 1
    Next
End Sub

That worked like a charm! Thank you so much! Would've been a hassle not being able to use what is already in Visio, so getting that to work was important to me.
Thanks everyone for your help!