Solved

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

Posted on 2009-03-31
19
3,287 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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
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
 
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The ability to add structure to Visio diagrams using containers, lists and callouts is one of my favorite features in Visio 2010. In this article I’ll describe a mashup of containers and lists that meet a real-world need. Prior to reading this ar…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

813 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

10 Experts available now in Live!

Get 1:1 Help Now