从 FormControl 切换 InfoPath 视图





5.00/5 (1投票)
InfoPath 无法执行任何与视图相关的对象模型调用。视图未准备就绪。
引言
这是一个尝试解决与托管在 Infopath FormControl
上的 Infopath 视图切换相关的常见问题之一。
背景
我相信没有多少开发人员在使用 Infopath FormControl
进行实验。 如果是这样,那么您可能遇到过在方法中连续切换视图和打印 Infopath 视图的问题。 从表面上看,这很简单。
for (int viewIndex = 0; viewIndex < formControl1.XmlForm.ViewInfos.Count; viewIndex++)
{
ViewInfo viewInfo = formControl1.XmlForm.ViewInfos[viewIndex];
formControl1.XmlForm.ViewInfos.SwitchView(viewInfo.Name);
}
但是当您在代码中尝试此操作时,您会得到以下 COM 异常
{"InfoPath cannot execute any view-related object model calls. The view is not ready."}
错误消息说视图未准备就绪,视图仍在切换,所以我的下一个尝试是通过 Sleep 延迟下一次切换。 我尝试了。 无论我提供多少延迟,这根本都行不通。
是的,当您的项目几乎完成时,这只是一个阻止您发布的功能,这很糟糕。 我一直在使用它,并找到了一个随时切换和打印 Infopath 页面的解决方法。 您必须付出额外的努力才能使其工作。
Using the Code
FormControl
的 ContextChanged
事件在这种情况下很有用。 contextChanged
事件是异步的。 它不会在上下文节点的每次更改时触发; 而是应用程序停止处理其他事件后触发。
因此,在表单的 InternalStartup
事件中绑定到 FormEvents_ContextChanged
事件。(当 SwitchView
方法切换并在表单的第一个控件上获得焦点时,FormEvents_ContextChanged
事件会触发。我相信这是就切换视图而言的最后一个事件触发。)
为了触发到下一个视图,我正在使用著名的信号机制。 从 Context changed 事件处理程序,我正在向 Form Control 发出信号以切换到下一个视图。 这看起来很简单,但是一旦我完成编码,除非我使用两个不同的 BeginInvoke
才能正确地发出信号,否则它将无法完成所需的工作。
首先 - 从 BeginInvoke
调用中调用 PrintFrom
//call the print - from a thread
PrintInvokerDelegate del = PrintInvoker;
del.BeginInvoke(null, null);
接下来 - 从另一个线程调用您的 SwitchViewDelegate
BeginInvoke(new SwitchViewDelegate(SwitchView), new object[] {viewIndex});
m_ar.WaitOne(3600, false);
并且 AutoResetEvent
在这里等待来自 ContextChanged
事件处理程序的信号。
另请确保在没有上述步骤的情况下打印第一个视图,因为如果您切换到同一视图,则不会触发 ContextChanged
事件。
通过将打印代码更改为 ExporttoPDf
来测试应用程序,从而节省纸张(您可能需要为此安装 Microsoft 插件)。
现在快乐地切换吧...
历史
- 2008 年 12 月 24 日:初始发布