http://www.cnblogs.com/lijun4017/archive/2008/04/28/1175323.html
当时XFORM的概念相当热,我也看了一些资料,觉得还是不太成熟,没有敢用。
后来看了微软office2007中的infopath,感觉功能非常强,它可以实现用infopath设计表单,然后用表单控件把表单嵌入到winform中去,并且可以实现表单中的数据加载和保存功能。但是唯一的遗憾就是如果要使用它,就必须要客户机器上安装office2007,这样就不太现实了。
最后来想到的是用xml+xslt是动态生成静态页面,然后把静态页面嵌入在winform的浏览器控件里面,并且屏蔽一些浏览器控件的一些属性,看起来就和winform设计的表单差不多了。这样就方便多了,我可以叫美工帮我设计表单,叫其他的asp.net的程序员帮忙做XML和XSLT以及里面的javascript脚本。后来的项目进展说明了,这种方式真的大大的提高了工作效率,也让我轻松了不少,嘿嘿,又偷懒了。
下面我说说具体的过程吧。
1。首先我在设计表的时候,把整个表单的内容设计成XML类型的字段,当然,其他需要搜索的字段还是要单独建字段,并且保存xslt文件的版本号。
2。设计表单的XML结构,下面是示例。
<!-- 现场会议记录 -->
< meetnote >
< enterprise ></ enterprise >
<!-- 会议名称 -->
< meets >
< meet >
< name > meet1 </ name >
< checked > false </ checked >
</ meet >
< meet >
< name > meet2 </ name >
< checked > false </ checked >
</ meet >
< meet >
< name > meet3 </ name >
< checked > false </ checked >
</ meet >
</ meets >
< compere />
< recorder />
< address />
< meetdate />
< content />
</ meetnote >
3.设计表单的XSLT文件,下面是示例。
< xsl:stylesheet xmlns:xsl = " http://www.w3.org/1999/XSL/Transform "
xmlns:msxsl = " urn:schemas-microsoft-com:xslt "
version = " 1.0 " >
< xsl:template match = " / " >
< html >
< head >
< link href = " ../css/xmltable.css " rel = " stylesheet " type = " text/css " />
< script language = " javascript " >
// 使用客户端日期JS脚本初始化
var date = new Date();
var Fun_Year = date.getYear();
var Fun_Month = date.getMonth() + 1 ;
var Fun_Day = date.getDate();
</ script >
< script language = " javascript " src = " ../javascript/calendar.js " ></ script >
< script language = " javascript " src = " ../javascript/check.js " ></ script >
< script language = " javascript " src = " ../javascript/common.js " ></ script >
< script language = " javascript " >
function validate()
{
var errorinfo="";
if(clearSpace(txtcompere.value)=="")
{
errorinfo += "主持人为空\n";
}
if(clearSpace(txtaddress.value)=="")
{
errorinfo+= "会议地点为空\n";
}
if(clearSpace(txtrecorder.value)=="")
{
errorinfo+="记录人为空\n";
}
if(clearSpace(txtmeetdate.value)=="")
{
errorinfo += "会议时间为空\n";
}
if(clearSpace(txtcontent.innerText)=="")
{
errorinfo+= "会议内容为空\n";
}
//会议名称
if(txtmeet1.checked != true && txtmeet2.checked != true && txtmeet3.checked != true)
{
errorinfo+= "请选择会议名称\n";
}
if(errorinfo=="")
{
return true;
}
else
{
window.external.ShowErrorMessage(errorinfo);
return false;
}
}
// 数据保存
function savetoxml()
{
var doc = new ActiveXObject("Msxml2.DOMDocument");
doc.async = false;
//调用c#方法获取xml文件路径
var xmlfilepath = window.external.GetXMLPathForJava();
doc.load(xmlfilepath);
//会议名称
doc.selectNodes("meetnote/meets/meet")[0].lastChild.text=(txtmeet1.checked==0)?'false':'true';
doc.selectNodes("meetnote/meets/meet")[1].lastChild.text=(txtmeet2.checked==0)?'false':'true';
doc.selectNodes("meetnote/meets/meet")[2].lastChild.text=(txtmeet3.checked==0)?'false':'true';
doc.selectSingleNode("meetnote/compere").text=txtcompere.value;
doc.selectSingleNode("meetnote/recorder").text=txtrecorder.value;
doc.selectSingleNode("meetnote/address").text=txtaddress.value;
doc.selectSingleNode("meetnote/meetdate").text=txtmeetdate.value;
doc.selectSingleNode("meetnote/content").text=txtcontent.innerText;
//调用c#方法保存xml文件
var examfiletype = window.external.GetExamFileType();
var examfilename = window.external.GetExamFileName();
window.external.Save(doc.xml,examfiletype,examfilename);
return true;
}
</ script >
</ head >
< body >
< xsl:apply - templates />
</ body >
</ html >
</ xsl:template >
< xsl:template match = " meetnote " >
< table border = " 1 " align = " center " cellPadding = " 0 " cellSpacing = " 0 " class = " table " >
< tr >
< td class = " td1 " colspan = " 4 " >
< div align = " center " class = " title " > 现场审核会议记录 </ div >
</ td >
</ tr >
< tr >
< td class = " td2 " >
< span > 受审核方: </ span >
< xsl:value - of select = " enterprise " />
</ td >
</ tr >
< tr >
< td class = " td2 " >
< span > 会议名称: </ span >
< xsl:apply - templates select = " meets/meet " />
</ td >
</ tr >
< tr >
< td class = " td2 " >
< span > 主 持 人: </ span >
< input style = " WIDTH: 150px; " type = " text " name = " txtcompere " >
< xsl:attribute name = " value " >
< xsl:value - of select = " compere " />
</ xsl:attribute >
</ input >
< span > 会议地点: </ span >
< input style = " WIDTH: 200px; " type = " text " name = " txtaddress " >
< xsl:attribute name = " value " >
< xsl:value - of select = " address " />
</ xsl:attribute >
</ input >
</ td >
</ tr >
< tr >
< td class = " td2 " >
< span > 记 录 人: </ span >
< input style = " WIDTH: 150px; " type = " text " name = " txtrecorder " >
< xsl:attribute name = " value " >
< xsl:value - of select = " recorder " />
</ xsl:attribute >
</ input >
< span > 会议时间: </ span >
< input style = " WIDTH: 100px; " type = " text " name = " txtmeetdate " onfocus = " calendar(); " id = " txtmeetdate " >
< xsl:attribute name = " value " >
< xsl:value - of select = " meetdate " />
</ xsl:attribute >
</ input >
</ td >
</ tr >
< tr >
< td valign = " top " class = " td2 " >
< span > 会议内容: </ span >
< br />
< textarea style = " WIDTH: 100%;HEIGHT:150px " type = " text " name = " txtcontent " >
< xsl:value - of select = " content " />
</ textarea >
</ td >
</ tr >
</ table >
</ xsl:template >
<!-- 会议名称 -->
< xsl:template match = " meets/meet " >
< xsl: if test = " name='meet1' " >
< input type = " checkbox " name = " txtmeet1 " id = " txtmeet1 " onclick = " radiobutton(this,'txtmeet') " >
< xsl: if test = " checked='true' " >
< xsl:attribute name = " checked " >
checked
</ xsl:attribute >
</ xsl: if >
</ input >
< span > 首次会议 </ span >
</ xsl: if >
< xsl: if test = " name='meet2' " >
< input type = " checkbox " name = " txtmeet2 " id = " txtmeet2 " onclick = " radiobutton(this,'txtmeet') " >
< xsl: if test = " checked='true' " >
< xsl:attribute name = " checked " >
checked
</ xsl:attribute >
</ xsl: if >
</ input >
< span > 沟通会议 </ span >
</ xsl: if >
< xsl: if test = " name='meet3' " >
< input type = " checkbox " name = " txtmeet3 " id = " txtmeet3 " onclick = " radiobutton(this,'txtmeet') " >
< xsl: if test = " checked='true' " >
< xsl:attribute name = " checked " >
checked
</ xsl:attribute >
</ xsl: if >
</ input >
< span > 末次会议 </ span >
</ xsl: if >
</ xsl:template >
</ xsl:stylesheet >
4。在XSLT文件中加入JS脚本,用户验证用户输入,收集表单数据,加载表单数据等。(这里涉及到JS代码和浏览器控件所在的winform窗体的代码的相互调用。)
1)首先把winform窗体的类加上这个属性[ComVisible(true)]
2) 在winform窗体里面写上public的方法
//取得xml文件路径(供javascript调用)
public string GetXMLPathForJava()
{
return tempxmlfilepath;
}
3)在XSLT文件里面的JS代码中调用这个方法
//调用c#方法获取xml文件路径
var xmlfilepath = window.external.GetXMLPathForJava();
4)在XSLT文件中定义JS方法
//数据保存
function savetoxml()
{
}
5)在winform窗体中调用JS方法
//调用JS方法
Object result = webBrowser1.Document.InvokeScript("savetoxml");
5.在显示页面的时候,我先使用下面的代码把XSLT和XML转换成HTML文件,存放在临时文件夹中,然后把浏览器控件的URL指向它。
string xsltemplatepath = TemplateHelper.GetFactoryFormXSLTemplatePath(m_FileType, m_DataRow.xsl_version);
try
{
transForm.Load(xsltemplatepath);
transForm.Transform(tempxmlfilepath, temphtmlfilepath);
}
catch (Exception ex)
{
LogError.Write(ex.Message + "\n" + ex.StackTrace);
MessageBox.Show("模板文件加载出错!");
this.Close();
return;
}
webBrowser1.Navigate(temphtmlfilepath);
6。在用户点击保存的时候,我通过XSLT中定义的JS代码,直接把用户保存的数据以XML的方式返回给winform的代码,然后保存到数据库中去。
if (Convert.ToBoolean(validateresult) == true )
{
Object result = webBrowser1.Document.InvokeScript("savetoxml");
if (Convert.ToBoolean(result) == true)
{
this.Close();
}
else
{
MessageBox.Show("保存出错", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
this.DialogResult = DialogResult.None;
}
}
else
{
this.DialogResult = DialogResult.None;
}
7。删除刚才产生的临时文件。