65.9K
CodeProject 正在变化。 阅读更多。
Home

从 FormControl 切换 InfoPath 视图

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2008 年 12 月 24 日

CPOL

2分钟阅读

viewsIcon

44012

downloadIcon

338

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

FormControlContextChanged 事件在这种情况下很有用。 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 日:初始发布
© . All rights reserved.