Reputation: 181
On Visio shapes on a Visio page, the only way to add Office Add-in functionality to the right-click mouse menu on Visio shapes is to use the QUEUEMARKEREVENT shapesheet function.
Unfortunately, this way of letting the user use functionality on a Visio shape is causing issues with the Undo/Redo system.
I have made some sample code below that can be dropped in to a new Visio VSTO VB.NET Project in Visual Studio (I use 2019, Visio also version 2019)
Compile the VSTO add-in and when Visio starts up, choose a Basic Diagram as that opens up the stencil I use for the test.
Drop one shape on the page and edit the ShapeSheet to add an Action Section, as per this screenshot:
On this shape in the right-click menu you will find the "Test" menu item. Run this item and a new Square shape will be added to the page.
Now use Undo and then perform a Redo. If you move the new shape you will see there is an identical square shape below it. A Redo doesn't add one but actually two new shapes.
I think I am misunderstanding something about how the QueueMarker events work I am very much just an amateur developer, hopefully someone knows how to fix this robustly as reliable Undo/Redo behavior is very important for a good add-in application. Thank you for sharing your insights!
Imports System.Windows.Forms
Imports System.Diagnostics
Imports System.Text
Imports Visio = Microsoft.Office.Interop.Visio
Partial Public Class ThisAddIn
Private Sub Application_MarkerEvent(app As Visio.Application, SequenceNum As Integer, ContextString As String) Handles Application.MarkerEvent
Dim Stencil As Visio.Document
Stencil = GetStencil()
If Stencil Is Nothing Then
MessageBox.Show("The Basic Shapes stencil is closed, please open it before running this action.")
Exit Sub
End If
Dim Square As Visio.Shape
Square = Application.ActivePage.Drop(Stencil.Masters.ItemU("Square"), 0, 0)
End Sub
Private Function GetStencil() As Visio.Document
Dim DocCounter As Long
For DocCounter = 1 To Application.Documents.Count
If Application.Documents(DocCounter).Type = Visio.VisDocumentTypes.visTypeStencil Then
If Application.Documents(DocCounter).Name = "BASIC_M.vssx" Or Application.Documents(DocCounter).Name = "BASIC_U.vssx" Then
'MessageBox.Show(Application.Documents(DocCounter).Name)
Return Application.Documents(DocCounter)
Exit Function
End If
End If
Next DocCounter
Return Nothing
End Function
End Class
Upvotes: 1
Views: 210
Reputation: 11
I think the MarkerEvent is generated twice on Redo. Can you check for the ContextString to be == "Test" before processing it and see if it helps?
Upvotes: 1