从当前选定的形状中读取 PinX、PinY ShapeSheet 单元格值:Visio、C# COM Interop
我试图通过键盘序列(例如 [Ctrl]+[G])为 Visio 中当前选定的形状设置 PinX 和 PinY 值。此工作的目的是根据当前所选形状的图钉坐标以编程方式将形状拖放到 Visio 绘图上。我使用 C# 和 Microsoft.Office.Interop.Visio API 来执行此操作。我正在使用 .NET 4.0(mscorlib.dll 版本为 4.0.30319.1)。
到目前为止,我有这段代码:
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
//...
}
此代码导致 COMException;经过调查,事实证明,即使 myApp.ActiveWindow.Selection 有一个元素 [0] (如果只选择一个形状,它是唯一的元素),但我无法实际将该元素存储到 currShape 中。我不知道这是为什么。奇怪的是,COMException 并没有导致程序停止。当尝试分配给 currShape 时,程序退出该方法,但执行会继续。
我尝试用另一种方法获取当前形状;这引发了相同的 COMException,只不过这次我能够查看它,因为与之前的异常不同,该异常停止了执行。
此代码:
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";
}
导致此异常:
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.Forms.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:
我不知道“无效的选择标识符”是什么意思,并且谷歌搜索仅产生 this 主题,适用于 Visual Basic 而不是 C#。
我的两个问题是:
(1) 这里出了什么问题?
(2) 访问当前选择的形状进行此类操作的正确方法是什么?
感谢您的任何帮助。
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.Forms.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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我过去在 Visio 中选择形状时遇到过麻烦。我的解决方法是创建一个 Selection 对象,然后使用 Select方法。我不确定这是否会对你有帮助。
另外,您还可以在 VisGuy.com 上交叉发布此内容。这就是 Visio 可编程性专家的所在。
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.
我想知道这个问题是否与 Selection 集合的索引有关。
尝试一下:
currShape = myApp.ActiveWindow.Selection.Cast().FirstOrDefault()
不要忘记通过
using System.Linq;
添加对 Linq 库的引用。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;
.事实证明,我需要访问 [1] 而不是 [0],例如
,因为 Visio 从 1 开始对对象进行编号。即使 myApp.ActiveWindow.Selection 上的 Visual Studio 中的 Watch 在 [0] 处只有一个对象,我还是使用 [1] 访问它。
It turns out that I needed to access [1] instead of [0], e.g.
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].