公告

目前关注于InfoPath + Workflow + SharePoint
任何.NET技术方面的合作可与我联系mazong1123img@163.com

2010-04-23 23:04:56
阅读完本文后, 你将可以自定义InfoPath Logic Inspector, 并且能够轻松地做到下图所示的改动.
 
Logic
 
我将会以一个更复杂且更实用的例子来示范如何自定义InfoPath Logic Inspector.
 
InfoPath Logic Inspector 的局限
 
InfoPath Logic Inspector最令人头痛的事莫过于无法复制其中的内容. 再加上它是一个模式对话框, 对于InfoPath 开发人员来说实在是不方便. 如果能够提供复制当前内容的功能, 将会方便很多.
 
InfoPath Logic Inspector 到底是什么?
 
既然InfoPath没有暴露任何有关Logic Inspector的接口, 那么就需要我们自己探索了. 首先要弄清楚Logic Inspector到底是由什么控件组成的. 使用Visual Studio的工具Spy++, 可以很容易查看到Logic Inspector实际上是一个IE控件.
 

OK. 接下来, 我们要将Logic Inspector中的内容抓取出来. 下面的代码展示了如何获取IE控件中的内容. 在文章的附件中会有完整的代码.
EnumWindows(new EnumWindowsProc(EvalWindow), IntPtr.Zero);               foreach (IntPtr hwnd in ipHwnds)              {                  StringBuilder sb = new StringBuilder(256);                  GetWindowText(hwnd, sb, 256);                   IntPtr hwndIPIE = IntPtr.Zero;                  IntPtr parentHwnd = hwnd;                  String className = String.Empty;                  while (!className.Equals("Internet Explorer_Server"))                  {                      EnumChildProc childProc = new EnumChildProc(EnumChildWindows);                      EnumChildWindows(parentHwnd, childProc, ref hwndIPIE);                      className = GetClassName(hwndIPIE);                      parentHwnd = hwndIPIE;                  }                   IHTMLDocument2 htmlDoc = IEDOMFromhWnd(hwndIPIE);                  String htmlText = htmlDoc.body.parentElement.outerHTML;                   StreamWriter sw = new StreamWriter(String.Format("d:\\{0}.html", sb.ToString()));                  sw.Write(htmlText);                  sw.Close();              }  
以下是从Logic Inspector 抓取的内容:
<html> <head>     <title>Logic Inspector</title>     <meta content="text/html; charset=utf-8" http-equiv="Content-Type"></meta> </head> <frameset id="idframeset" framespacing="2" border="2" cols="50%,50%"> <FRAME id=overallFrame src="res://1033\ipdsintl.dll/InspectorOverallFrames.html" scrolling=yes> <FRAME id=fieldFrame src="res://1033\ipdsintl.dll/InspectorFieldFrames.html" scrolling=yes> </frameset> </html> 
很明显, Logic Inspector 由2个Frame组成: "overallFrame" 和 "fieldFrame". 从名字即可知道"overallFrame"指代Logic Inspector的左半部, "fieldFrame" 指代Logic Inspector的右半部.
如果你足够细心, 就会发现一个奇妙的地方. 这2个Frame的source居然是从一个dll中读取的. 而这个ipdsintl.dll就是揭开InfoPath 秘密的重点.
IPDSINTL.DLL -- InfoPath 的资源文件
首先我们要找到IPDSINTL.DLL到底在哪. 从它的上级目录"1033"来看, 这个文件应该在Microsoft Office文件夹下. 如我所料, 它确实是老老实实呆在这的:
%ProgramFiles%\Microsoft Office\Office12\1033\IPDSINTL.DLL
把这个DLL拖到Visual Studio中, 可以看到其实它是InfoPath重要的资源文件.
 
 
还记得2个frame的路径吗? 赶紧看看HTML文件夹下的内容吧:
 



2010-03-21 12:08:31
InfoPath 内置错误查找功能的局限及原因
 
InfoPath 内置的错误查找功能只能定位当前视图的错误, 并且一次只能定位一个.

 
这样看似匪夷所思的设计, 其实是因为InfoPath整体设计导致的. 首先, 这里所说的错误是针对数据而言的, 例如field1不能为空. 考虑以下情况:
 
1. field1在view1和view2中都有绑定的控件.
2. field1没有任何绑定的控件.
 
对于情况1, 从视图的角度来看, 应该有2个错误分别存在于view1和view2中; 以数据而言, 只有1个错误.
对于情况2, 从视图的角度来看, 没有错误; 以数据而言, 有1个错误.
 
很显然, 为了正确地判断错误信息, 应该从数据的角度来看待错误, InfoPath正是这样看待错误的. 因此, InfoPath的错误信息中并不保存视图信息, 这也导致"Go to Next Error"只能定位到当前视图上含有错误信息的控件.
 
扩展InfoPath错误查找功能
 
InfoPath内置查看功能的最大局限就在于无法跨视图定位含有错误的Field绑定的所有控件。为了扩展其功能,需要2个步骤:
 
1. 获取当前表单的所有错误字段。
2. 获取字段绑定的控件所在视图。
3. 切换到错误控件所在视图并选中该控件。
 
对于步骤1,可以使用Microsoft.Office.Interop.InfoPath.XDocument.Errors.
 
对于步骤2,首先要获取当前表单的模板(xsn)位置,可以使用
Microsoft.Office.Interop.InfoPath.XDocument.Solution.URI
. 其次解压xsn文件,再在*.xsl文件中查找错误字段。
 
对于步骤3,使用Microsoft.Office.Interop.InfoPath.XDocument.View.SwitchView 切换视图,并使用Microsoft.Office.Interop.InfoPath.XDocument.View.SelectText选中错误字段绑定的控件。
 
完成了以上3个步骤,扩展错误查找功能基本就完成了。
 
InfoPath 错误查看器 (InfoPath Error Viewer)
 
可以利用InfoPath Add-in的开发技术将错误查找功能集成到InfoPath中,这样,一个新的插件InfoPath Error Viewer就诞生了。


 
下载 InfoPath Error Viewer
 
注意:安装时请右键-〉以管理员身份运行[/img]..



2010-03-20 11:52:31



2010-03-17 16:49:57



2010-01-15 15:05:01



2010-01-06 19:41:34



2009-12-18 15:01:34



2009-10-06 09:17:21



2009-09-03 12:41:45



2009-08-23 15:38:46



 <<   1   2   >>   页数 ( 1/2 )