• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3672
  • Last Modified:

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

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
paix120
Asked:
paix120
  • 14
  • 5
1 Solution
 
paix120Author Commented:
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
 
paix120Author Commented:
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
 
paix120Author Commented:
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
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
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
 
paix120Author Commented:
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
 
paix120Author Commented:
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
 
paix120Author Commented:
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
 
Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
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
 
paix120Author Commented:
OK thanks for the ideas I will try them out soon! I think this is what I was looking for.
0
 
paix120Author Commented:
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
 
paix120Author Commented:
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
 
Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
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
 
paix120Author Commented:
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
 
Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
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
 
paix120Author Commented:
Awesome, thanks for your help. I will have time to try this suggestion out tonight and I'll get back to you.
0
 
paix120Author Commented:
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
 
paix120Author Commented:
Declaring the Visio.Application object WithEvents and using the CellChanged event to detect shape location changes was exactly what I needed!
0
 
paix120Author Commented:
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
 
Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
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

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

  • 14
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now