posts - 24,  comments - 23,  trackbacks - 0
公告

 

转载:http://blog.csdn.net/yanwei100/archive/2006/05/16/740766.aspx

InfoPath采用XML存储数据。

开发人员可以使用thisXDocument对象对InfoPath的数据进行访问。

1  访问field数据,需要注意的是要先设置XPath和Namespaces

            tempDom = (IXMLDOMDocument2)thisXDocument.DOM;
            tempDom.setProperty("SelectionLanguage", "XPath");
            tempDom.setProperty("SelectionNamespaces",
                "xmlns:dfs=\"" + "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" +
                "\" xmlns:my=\"http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-05-12T03-20-30/"");
            nodeEntry = tempDom.documentElement.selectSingleNode("my:Name");


 2 修改field数据

            nodeEntry.text = "123";

3 插入group节点.

这里,我们先取得第一个Tasks节点。克隆此节点,然后把这个节点插入。最后,删除原来的Tasks节点。

            IXMLDOMDocument2 tempDom;
            IXMLDOMNode nodeEntry;
            tempDom = (IXMLDOMDocument2)thisXDocument.DOM;
            tempDom.setProperty("SelectionLanguage", "XPath");
            tempDom.setProperty("SelectionNamespaces",
                "xmlns:dfs=\"" + "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" +
                "\" xmlns:my=\"http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-05-12T03-20-30/"");
            nodeEntry = tempDom.documentElement.selectSingleNode("my:Tasks");
            IXMLDOMNode node;
            node = nodeEntry.cloneNode(false);

            IXMLDOMNodeList list = tempDom.documentElement.selectNodes("my:Tasks");

            try
            {   nodeEntry.parentNode.appendChild(node);

                //需要注意的是如果要删除原来的Tasks节点,需要在appendChild新节点后进行。否则,当删除了所有Tasks节点后,appendChild(node)会失败。
                foreach (IXMLDOMNode nd in list)
                {
                    nodeEntry.parentNode.removeChild(nd);
                }

            }            
            catch (Exception ex)
            {

            }

  在开发中,又遇到了问题。如果你修改了group节点的一些属性,具体是那些属性忘了,调用appendChild(node)会失败,解决的方法是使用insertBefore方法代替。

4 动态改变web的调用地址

我用一个field来保存要调用webservice的url地址,在启动时读入,在调用时修改dataobject的url

        public void OnLoad(DocReturnEvent e)
        {
            // Write your code here.
            IXMLDOMNode node = e.XDocument.DOM.documentElement.selectSingleNode("my:txtWebSiteURL");
            this.WebSiteURL = node.text;
        }

        private void ApplyWebServiceURL(DataObject dataObj)
        {
            WebServiceAdapter adp = dataObj.QueryAdapter as WebServiceAdapter;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(adp.Operation);
            XmlNode node = doc.SelectSingleNode("//@serviceUrl");
            node.Value = this.WebSiteURL;
            adp.Operation = doc.OuterXml;
        }

5 调用web service

            //找到要调用的dataconnect
            DataObject dataObj = (DataObject)thisXDocument.DataObjects["SaveEvent"];
            if (dataObj == null)
            {
                thisXDocument.UI.Alert("The data connect SaveEvent does not exist.");
                return null;
            }
            //设置Web service的输入参数,这里我要把整个xml数据作为输入参数
            IXMLDOMNode nodeEntry;
            try
            {
                nodeEntry = dataObj.DOM.selectSingleNode("/dfs:myFields/dfs:queryFields/tns:SaveEvent");
                nodeEntry.selectSingleNode("tns:input").text = dataObj.DOM.xml;
            }
            catch (Exception ex)
            {
                string err = ex.Message;
            }
            //调用Web service
            this.ApplyWebServiceURL(dataObj);
            dataObj.Query();
            //得到Web service的返回值,是一个xmldocument,包括projectID,eventID两个值
            IXMLDOMNode nodeResult = dataObj.DOM.selectSingleNode("/dfs:myFields/dfs:dataFields/tns:SaveEventResponse/tns:SaveEventResult");
            string projectID,eventID;
            projectID = nodeResult.selectSingleNode("//ProjectID").text;
            eventID = nodeResult.selectSingleNode("//EventID").text;

6 设置web service的超时长度

我的web service有时会很慢,系统默认的time out=30秒,这就导致我的form常常在调用时发生超时的异常。下面的代码将超时长度设置为120秒。

            DataObject dataObj = (DataObject)thisXDocument.DataObjects["CheckAllResources"];
            WebServiceAdapter2 adp = dataObj.QueryAdapter as WebServiceAdapter2;
            adp.Timeout = 120;

 7 用代码控制button的状态

 我的infopath需要根据当前用户的角色来控制用户的操作,具体就是如果用户有保存权限,Save按钮处于Enable状态,否则将Save按钮设置为disable状态。

InfoPath的按钮都有conditional formating功能,我们可以根据conditional formating的结果来控制按钮的状态或字体颜色等显示属性。conditional formating提供了简单的计算,如myfield1的值是否等于1;或当前用户的role是否等于某一个角色。

如果这些简单的计算不能满足你的需要,还有一种xdExtension的计算方式,是可以调用你自己的代码

1)首先需要在你的代码中定义一个计算函数,我这里的函数是取一个field的bool值并返回

        public bool SaveEnable()
        {
            string enable = thisXDocument.DOM.selectSingleNode("/my:myFields/my:SaveEnable").text;
            if (enable.ToUpper() == "TRUE")
            {
                return true;
            }
            else
            {
                return false;
            }
        }

2) 定义按钮的conditional formating,

在按钮上右键菜单选择

button properties -> Display  ->  Conditional Formatting... ->  Add,

在对话框中设置条件,左侧下拉选择The expression, 然后输入:

xdExtension:SaveEnable() != string(true())

选中Disable this control,然后确定。

8。 处理允许为空字段。在向允许为空字段内写入数据时,需要将节点的xsi:nil属性删除

nodeEntry.attributes.removeNamedItem("xsi:nil"); 

 

 9。巧用web service提高启动速度

我的项目中使用 InfoPath 2003作客户端,由于我的表单上有很多的dropdown list,在启动时非常慢。经过一个小的调整,启动速度快多了。

原来,每一个dropdown list数据源都是一个独立的data connect,连接到服务器的web service。因此,每次启动时,要依次初始化dropdown list,每个dropdown list都会调用一次web service,而web service是很慢的。造成启动速度慢。

为了提高速度,我调整了data connect,为所有的dropdown list建一个web service,将原来每个web service的返回结果添加到一个xml的根下面,这样,整个启动期间只要调用一次就可以了。

例如,我原来有2个dropdown list,分别是部门和人员,对应服务器端两个web service,

public XmlDocument GetDepartments(),  public XmlDocument  GetContacts()。

现在,我在服务器端增加一个web service方法public XmlDocument GetInitData(), 这个方法的返回值是一个xml文档,里面有两个子节点,一个存放GetDepartments的结果,另一个存放GetContacts的结果。需要注意的是,一定要保证各个数据结果集的名字是不重复的。如果使用的是DataSet直接转换的xml,需要保证每个表的名字是不重复的。

posted on 2008-04-21 10:26 ◎寶☆呗 阅读(...) 评论(...) 编辑 收藏