Solved

Trigger event on shape drag & drop in Visio Drawing Control (embedded in windows form, VB.NET)

Posted on 2009-03-31
19
3,237 Views
Last Modified: 2012-05-06
I have a Visio ActiveX Drawing Control (axMicrosoft.Office.Interop.VisOcx.AxDrawingControl) embedded in my VB.NET windows form. I am able to dynamically draw shapes on the Visio page. What I need to do next is allow the user to drag & drop a shape, then pop up a message box with the new visio drawing coordinates.

Problem is, I can't figure out which event is triggered by dragging and dropping a shape in the control. I have put several of the control's events in my code, and none are firing.

Does anyone know which event is associated with the shape drag & drop action? Also, is there an easy way to determine the coordinates of the dropped shape in this event using a value such as eventargs X and Y?

Thank you!
0
Comment
Question by:paix120
  • 14
  • 5
19 Comments
 
LVL 3

Author Comment

by:paix120
ID: 24026390
Note: I see a ShapeChanged event here (not sure if this would help), but it is not an available option in my control's event dropdown.
http://msdn.microsoft.com/en-us/library/ms366895.aspx
0
 
LVL 3

Author Comment

by:paix120
ID: 24026425
I have a feeling I need info from here, but I have no idea where to start with this:
http://msdn.microsoft.com/en-us/library/ms367505.aspx#
0
 
LVL 3

Author Comment

by:paix120
ID: 24026532
I found this:
http://www.experts-exchange.com/Microsoft/Applications/Microsoft_Visio/Q_23253022.html

and added modAddAdvise and clsEventSink to my project... am I getting anywhere? I don't know what to try next.
0
 
LVL 30

Expert Comment

by:Scott Helmers
ID: 24029726
I don't think you need to worry about AddAdvise, et. al.

Instead, I think you need an event of the Page object not the shape that you're dropping. Take a look at the ShapeAdded event of the Page object:
   http://msdn.microsoft.com/en-us/library/ms366857.aspx

As far as getting the coordinates, the shape contains two shapesheet cells call PinX and PinY that are at the center of the shape. If shp is your shape object (identified as a result of the ShapeAdded event mentioned above), then
    shp.CellsU("PinX").Result (visInches)
    shp.CellsU("PinY").Result (visInches)
will give you the X/Y coordinates in inches (from the lower left corner of the page).
0
 
LVL 3

Author Comment

by:paix120
ID: 24035777
Thanks - will ShapeAdded detect when I just move a shape on the page, though? Since I'm not actually adding anything? I'll try it out - thanks!

0
 
LVL 3

Author Comment

by:paix120
ID: 24035894
Nope - that event triggered every time my code dynamically added a shape, and also if I cut and pasted a shape, but not when I dragged & dropped a shape on the page.

Also, I'm familiar with PinX and PinY when placing shapes for the first time, but how can I get those values "on drop"? That's what I'm going for.

Thanks!
0
 
LVL 3

Author Comment

by:paix120
ID: 24035904
Just to be clear - I'm not talking about dragging & dropping a shape from the toolbar onto the page. I mean drag/drop to move a shape that's already on the page, then determining its new location where the user dropped it.
0
 
LVL 30

Expert Comment

by:Scott Helmers
ID: 24041681
Maybe I read your question wrong -- you asked about an event related to drag and drop, which to me implied that you're dragging a shape from a stencil and dropping it on the page. That would fire the ShapeAdded event, just as creating a shape in your code does.

By drag and drop do you just mean moving a shape? If so, one option is to set a formula in the EventXFMod cell in the event section of the shape. That will fire every time you "transform" the shape, i.e., move it. If you use the CALLTHIS() shapesheet function to call your code, Visio passes the apporpriate shape object to your code.

If you don't want to use the shapesheet, you could use the CellChanged event to check whether PinX or PinY has changed.
0
 
LVL 3

Author Comment

by:paix120
ID: 24041823
OK thanks for the ideas I will try them out soon! I think this is what I was looking for.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 3

Author Comment

by:paix120
ID: 24047519
OK now I am working in VB.NET with a visio drawing control, not in Visio/VBA itself. I have code to assign a function to the shape object, like so -

....CellsSRC(VisSectionIndices.visSectionObject, VisRowIndices.visRowEvent, VisCellIndices.visEvtCellXFMod).FormulaU = "...

Now, what can I put in the quotes that will work? I tried putting the name of a function in my form/class, but of course it doesn't recognize that name from inside the shape inside the visio control. I know this code is normally saved in a module in a visio document, but I need to trigger code in my VB.NET project to run. I'm a little confused as to how to do that.

I can't test whether this works until I find a formula that won't get the "Unknown function name." error.

However, I think we're on the right track! Any direction with where to go from here?

Thank you for your help so far!
0
 
LVL 3

Author Comment

by:paix120
ID: 24047528
If you can help me get to the point where I can pop up a message box in my VB.NET program when a shape is moved, I will be satisfied enough to give you the points! Thanks!
0
 
LVL 30

Expert Comment

by:Scott Helmers
ID: 24048990
I always find wrestling with quotes in code that is writing to shapesheet cells to be annoying...

The VBA code below does the job, however, and I assume it should work for VB.NET as well but let me know.


Sub SetEFX()

' set CallThis() function into EventXFMod cell of selected shape
 

    Dim shp As Shape

    Set shp = ActiveWindow.Selection(1)

    

    shp.CellsSRC(visSectionObject, visRowEvent, visEvtCellXFMod).FormulaU = _

        "CallThis(""ShowNewXY"")"

End Sub
 

'=  =  =  =  =  =  =  =  =  =  =  =  =  =
 

Sub ShowNewXY(visShape As Shape)

    MsgBox "New PinX is " & visShape.Cells("PinX").Result(visInches) & vbCrLf & _

        "New PinY is " & visShape.Cells("PinY").Result(visInches)

End Sub

Open in new window

0
 
LVL 3

Author Comment

by:paix120
ID: 24051522
I think the problem with the "CallThis" function is going to be that in VBA, both the callthis and the function are in the visio file itself, where on my form, the CallThis is being assigned to the cell like in yours, but the function is in my VB.NET windows forms code.

I'll see what I can do and get back to you. Thanks so much for your help!
0
 
LVL 30

Accepted Solution

by:
Scott Helmers earned 300 total points
ID: 24051833
You're right -- CallThis() does expect the code to be in the VB project. I should have thought of that.

In that case, let's revert to my other suggestion above -- use the CellChanged event. When the event fires and passes a cell, the code below will display the new PinX and Y. BTW, the CellChanged event fires for every cell that changes -- in this case, both PinX and PinY are changed when you move the shape so the event will fire twice. Consequently, the if test only pops the message box for one of the events.

Private WithEvents vsoApplication As Visio.Application
 

Public Sub CellChanged_Example()

    'Set a module-level variable to trap application-level events.

    Set vsoApplication = Application

End Sub
 

Private Sub vsoApplication_CellChanged(ByVal vsoCell As IVCell)

    If vsoCell.Name = "PinX" Then

        MsgBox "For shape " & vsoCell.Shape.Name & ":" & vbCrLf & _

            "New PinX is " & vsoCell.Shape.Cells("PinX").Result(visInches) & vbCrLf & _

            "New PinY is " & vsoCell.Shape.Cells("PinY").Result(visInches)

    End If

End Sub

Open in new window

0
 
LVL 3

Author Comment

by:paix120
ID: 24052870
Awesome, thanks for your help. I will have time to try this suggestion out tonight and I'll get back to you.
0
 
LVL 3

Author Comment

by:paix120
ID: 24056319
Yes, this is exactly what I needed! Thank you! I already had an application object on my page, but didn't have it declared WithEvents.

The only problem I had was that it also fired every time a shape was dynamically created on my code (about 50 times on load), so I just created a boolean that I can use to 'turn off' the shape move event when I am initially drawing the shapes on. Easy fix! Below is my final version.

THANK YOU!


Private WithEvents vsoApplication As Visio.Application
 

'i use this in other parts of my code to turn it off when initially loading the shapes    

Dim booDetectShapeMove As Boolean = False
 

    Private Sub ShapeMoved(ByVal vsoCell As Visio.IVCell) Handles vsoApplication.CellChanged

        If booDetectShapeMove = True Then

            If vsoCell.Name = "PinX" Then

                MsgBox("For shape " & vsoCell.Shape.Name & ":" & vbCrLf & _

                    "New PinX is " & vsoCell.Shape.Cells("PinX").Result(Visio.VisUnitCodes.visInches) & vbCrLf & _

                    "New PinY is " & vsoCell.Shape.Cells("PinY").Result(Visio.VisUnitCodes.visInches))

            End If

        End If

    End Sub

Open in new window

0
 
LVL 3

Author Closing Comment

by:paix120
ID: 31564710
Declaring the Visio.Application object WithEvents and using the CellChanged event to detect shape location changes was exactly what I needed!
0
 
LVL 3

Author Comment

by:paix120
ID: 24056843
For future reference, this is my exact sub:

    Private Sub ShapeMoved(ByVal vsoCell As Visio.IVCell) Handles vsoApplication.CellChanged
 

	'this sub runs any time a shape is dragged & dropped on the Visio page
 

	'booDetectShapeMove is set to true after the initial items are loaded onto the page from the database

        If booDetectShapeMove = True And (vsoCell.Name = "PinX" Or vsoCell.Name = "PinY") Then

            'show 'move' label and new location coordinates in textboxes

            txtMoveLabel.Text = ""

            txtMoveLabel.Visible = True

            txtXLoc.Visible = True

            txtYLoc.Visible = True

            cmdSaveLoc.Visible = True
 

            If vsoCell.Shape.Data1 = "ITEM" Then

                'ask user if they want to save item location

                txtMoveLabel.Text = "You moved Item " & vsoCell.Shape.Data2.ToString & _

                    ". Click Save below to store this new location in the database. To revert, click 'Show Items' above."

            End If
 

            'Show the new coordinates in the textboxes

            txtXLoc.Text = vsoCell.Shape.Cells("PinX").Result(Visio.VisUnitCodes.visInches)

            txtYLoc.Text = vsoCell.Shape.Cells("PinY").Result(Visio.VisUnitCodes.visInches)
 

        End If

     End Sub

Open in new window

0
 
LVL 30

Expert Comment

by:Scott Helmers
ID: 24058586
I'm glad the CellChanged event did the trick. And thanks for posting your final code -- it's always more interesting when everyone gets to see how you applied the answer.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now