【问题标题】:Read PinX, PinY ShapeSheet cell values from currently selected Shape: Visio, C# COM Interop从当前选定的形状中读取 PinX、PinY ShapeSheet 单元格值:Visio、C# COM 互操作
【发布时间】:2011-03-23 16:52:16
【问题描述】:

我正在尝试在键盘序列上为 Visio 中当前选定的形状设置 PinX 和 PinY 值,例如[Ctrl]+[G]。这项工作的目的是根据当前选定形状的引脚坐标以编程方式将形状拖放到 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) 访问当前选择的形状以进行这种操作的正确方法是什么?

感谢您的帮助。

【问题讨论】:

  • 由于某种原因,我再也看不到任何已发布的答案...

标签: c# interop com-interop visio


【解决方案1】:

过去,我在 Visio 中选择形状时遇到过麻烦。我的解决方法是创建一个 Selection 对象,然后使用 Select 方法。我不确定这是否会对您有所帮助。

另外,您可以在VisGuy.com 交叉发布此内容。这就是 Visio 可编程性专家所在。

【讨论】:

  • 感谢您的回答。我弄清楚了它是什么(而且我之前没有弄清楚这一点真是太愚蠢了)。
【解决方案2】:

我想知道这个问题是否与 Selection 集合的索引有关。

试试这个:

currShape = myApp.ActiveWindow.Selection.Cast<Shape>().FirstOrDefault() 不要忘记通过using System.Linq;添加对Linq库的引用​​。

【讨论】:

  • 感谢您的回答,问题确实与 Selection 集合的索引有关。使用 [1] 有效。
【解决方案3】:

原来我需要访问 [1] 而不是 [0],例如

currShape = myApp.ActiveWindow.Selection[1];

因为 Visio 从 1 开始对对象进行编号。即使 Visual Studio 中 myApp.ActiveWindow.Selection 上的 Watch 在 [0] 处只有一个对象,我必须使用 [1] 访问它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-18
    • 2019-02-02
    • 1970-01-01
    • 2017-03-30
    相关资源
    最近更新 更多