Read PinX, PinY ShapeSheet cell values from currently selected Shape: Visio, C# COM Interop
I am trying to set the PinX and PinY values for the currently selected shape in Visio on a keyboard sequence, e.g. [Ctrl]+[G]. The purpose of this endeavor is to programmatically drop a shape onto the Visio drawing based on the pin coordinates of the currently selected shape. I am using C# and the Microsoft.Office.Interop.Visio API to do this. I am using .NET 4.0 (mscorlib.dll is version 4.0.30319.1).
So far I have this code:
Application myApp; // the reference to the Visio Application instance, which is passed into this class via constructor
Shape currShape; // a global variable for this class
//... down to the method in question
void app_KeyUp(int KeyCode, int KeyButtonState, ref bool CancelDefault)
{
currShape = myApp.ActiveWindow.Selection[0];
String xCoord = currShape.get_Cells("PinX").Formula;
String yCoord = currShape.get_Cells("PinY").Formula;
//handle keyboard events here
//...
}
This code causes a COMException; after investigating, it turns out that even though myApp.ActiveWindow.Selection has an element [0] (its only element if only one shape is selected), I am not able to actually store that element into currShape. I do not know why that is. Strangely enough, the COMException does not cause the program to stop. The program exits out of the method when trying to assign to currShape, but execution continues.
I tried getting the current shape in another method; this raised the same COMException, except this time I was able to get a look at it because this exception stopped execution, unlike the previous.
This code:
public void test()
{
currShape = myApp.ActiveWindow.Selection[0];
String x = currShape.Shapes[1].get_Cells("PinX").Formula;
currShape.Shapes[1].get_Cells("PinX").FormulaForce = "5";
}
caused this exception:
System.Runtime.InteropServices.COMException was unhandled
Message="\n\nInvalid selection identifier."
Source="Microsoft Visio"
ErrorCode=-2032465753
StackTrace:
at Microsoft.Office.Interop.Visio.SelectionClass.get_Item(Int32 Index)
at WindowsFormsApplication4.Handler.test() in C:\Users\pvs5x\Documents\Visual Studio 2008\Projects\ACCESS(1)\Handler.cs:line 91
at WindowsFormsApplication4.Form3.changeColorToolStripMenuItem_Click(Object sender, EventArgs e) in C:\Users\pvs5x\Documents\Visual Studio 2008\Projects\ACCESS(1)\OpenSafetyCase.cs:line 355
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Form开发者_运维知识库s.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at WindowsFormsApplication4.Program.Main() in C:\Users\pvs5x\Documents\Visual Studio 2008\Projects\ACCESS(1)\Program.cs:line 20
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
I have no clue what "Invalid selection identifier" means, and Googling only yields this topic, which is for Visual Basic and not C#.
My two questions are:
(1) What is going wrong here? (2) What is the proper way to access the currently selected shape for this kind of manipulation?Thanks for any help.
I've run into troubles with selecting shapes in Visio in the past. How I solved it was by creating a Selection object and then using the Select method. I'm not sure if that will help you.
Also, you might cross-post this at VisGuy.com. That's where the Visio programmability experts are.
I wonder if the issue is related to the index of the Selection collection.
Give this a try:
currShape = myApp.ActiveWindow.Selection.Cast<Shape>().FirstOrDefault()
Dont forget to add a reference to Linq library by using System.Linq;
.
It turns out that I needed to access [1] instead of [0], e.g.
currShape = myApp.ActiveWindow.Selection[1];
because Visio starts numbering objects from 1. Even though the Watch in Visual Studio on myApp.ActiveWindow.Selection had only one object at [0], I had to access it using [1].
精彩评论