﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-ASP.NET 报表软件 南京袁永福</title><link>http://www.cnblogs.com/xdesigner/</link><description>沉痛悼念中国最重要的科学家钱学森先生-擎天天博报表软件，支持B/S、C/S、ASP.NET,支持微软.NET1.1/2.0/3.0袁永福 江西九江人 2001年东南大学动力系毕业 电子邮箱:yyf9989@hotmail.com QQ群:41118220</description><language>zh-cn</language><lastBuildDate>Wed, 10 Feb 2010 10:08:29 GMT</lastBuildDate><pubDate>Wed, 10 Feb 2010 10:08:29 GMT</pubDate><ttl>60</ttl><item><title>C#发现之旅 --- WinForm.NET中开发具有固定背景图片的可滚动控件</title><link>http://www.cnblogs.com/xdesigner/archive/2009/11/09/fixed-background-control.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Mon, 09 Nov 2009 12:40:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/11/09/fixed-background-control.html</guid><description><![CDATA[<p>阅读: 1664 评论: 8 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-11-09 20:40 <a href="http://www.cnblogs.com/xdesigner/archive/2009/11/09/fixed-background-control.html" target="_blank">原文链接</a></p><p><span style="font-family: 宋体; font-size: 24pt"><strong>摘要</strong></span></p><span style="font-family: 宋体">
<p style="text-indent: 21pt; margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在本文章中笔者使用</span><span lang="EN-US"><font face="Times New Roman">WinForm.NET2.0</font></span><span style="font-family: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发出一个具有固定背景图片的带滚动条的容器控件。点击下载本文章配套的演示程序 <a href="http://files.cnblogs.com/xdesigner/FixedBackground.zip" target="_blank">/Files/xdesigner/FixedBackground.zip</a>。</span></p>
<p></span>&nbsp;</p>
<p><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp; 在</span>WinForm.NET<span style="font-family: 宋体">开发中，可以使用一个</span>Panel<span style="font-family: 宋体">或</span>UserControl<span style="font-family: 宋体">作为一个带滚动条的容器放置图形或其他控件。我们可以设置控件的</span>BackgroundImage<span style="font-family: 宋体">属性来设置控件的背景图片，但这个背景图片是会随着控件内容的滚动而滚动的，而且还出现背景破碎的不良效果。现笔者在开发实践中遇到控件的背景图片不随着控件的滚动而滚动。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在</span>B/S<span style="font-family: 宋体">开发中，开发者可以使用&#8220;</span>background-attachment:fixed<span style="font-family: 宋体">&#8221;的</span>CSS<span style="font-family: 宋体">样式来固定</span>HTML<span style="font-family: 宋体">文档的背景图片，使之不随着内容的滚动而滚动。但在</span>WinForm.NET<span style="font-family: 宋体">开发中却没这个功能。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">于是袁某人又开始路漫漫其修远兮，到处上下而求索，居然得出了一个解决方法，在此使用发现问题，分析问题和解决问题的步骤来一一道来，希望能为遇到相同问题的人一点启发。</span></p>
<p><strong><span style="font-family: 宋体; font-size: 22pt">发现问题</span></strong><strong><span style="font-size: 22pt"></span></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">首先说说</span>WinForm.NET<span style="font-family: 宋体">滚动时背景也随之滚动的原理。如下图所示，笔者在一个窗体上放置一个</span>Panel<span style="font-family: 宋体">控件，设置了一个尺寸较大的背景图片，然后设置控件的</span>AuotScroll<span style="font-family: 宋体">值为</span>true<span style="font-family: 宋体">，设置控件的</span>AutoScrollMinSize<span style="font-family: 宋体">属性值为背景图片的大小，则这个控件就会如下图所示的显示滚动条。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixgb001.jpg" width="387" height="379" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者向下拖拽控件的垂直滚动条，使得控件的内容发生滚动。在默认情况下，</span>Windows<span style="font-family: 宋体">操作系统会自动实现控件客户区视图的滚动，例如滚动操作导致了</span>100<span style="font-family: 宋体">个像素的滚动距离，</span>Windows<span style="font-family: 宋体">会自动的将控件客户区显示的内容向上平移</span>100<span style="font-family: 宋体">个像素，于是控件下方新腾出来</span>100<span style="font-family: 宋体">个像素高度的客户区，这个客户区就是控件的无效矩形，</span>Windows<span style="font-family: 宋体">操作系统会向控件发送</span>WM_PAINT<span style="font-family: 宋体">消息，导致触发控件的</span>Paint<span style="font-family: 宋体">事件，从而调用程序代码来重新绘制这</span>100<span style="font-family: 宋体">个像素高度的区域。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p style="text-indent: 21pt"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg002.jpg" width="387" height="377" /></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt">Panel<span style="font-family: 宋体">控件内部处理</span>Paint<span style="font-family: 宋体">事件来绘制背景图片，此时即使控件的内容发生滚动，但绘制图形使用的</span>XY<span style="font-family: 宋体">坐标系仍然是以控件的左上角为原点的。而且由于无效矩形只有控件客户区最下面的</span>100<span style="font-family: 宋体">个像素的高度，而无效矩形之上的部分是不会重新绘制的，于是控件重新绘制了一部分的背景图片，于是导致如下的用户界面。这个用户界面是破碎的，是不能见人的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg003.jpg" width="390" height="379" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者让其他窗体完全覆盖掉这个控件后关闭覆盖窗体，则控件的所有的客户区都是无效区域，</span>Windows<span style="font-family: 宋体">操作系统会向控件发送</span>WM_PAINT<span style="font-family: 宋体">消息来触发控件的</span>Paint<span style="font-family: 宋体">事件，而控件内容会自动处理</span>Paint<span style="font-family: 宋体">事件并重新完整的绘制背景，从而形成如下效果。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg004.jpg" width="389" height="380" /></span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: 宋体; font-size: 22pt">分析问题</span></strong><strong></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">根据上述观察到的现象可以知道</span>WinForm.NET<span style="font-family: 宋体">控件天生具有固定背景的功能，其背景图片是不随控件的滚动而滚动。但</span>Windows<span style="font-family: 宋体">的默认滚动图形的操作却破坏了这个功能，从而造成了控件滚动时背景破碎的现象。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">根据上述的原理，笔者可以得出，只要阻止</span>Windows<span style="font-family: 宋体">默认的滚动图形的操作即可保护</span>WinForm.NET<span style="font-family: 宋体">控件的天生的固定背景的功能，从而实现固定背景的带滚动的控件。</span></p>
<p style="text-indent: 21pt">WinForm.NET<span style="font-family: 宋体">并没有提供任何禁止</span>Windows<span style="font-family: 宋体">默认滚动图形的功能，于是笔者使用到了一个强大的</span>Win32API<span style="font-family: 宋体">函数，那就是</span>LockWindowUpdate<span style="font-family: 宋体">。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个</span>API<span style="font-family: 宋体">函数在</span>C#<span style="font-family: 宋体">中的声明形式如下</span><span style="font-family: 宋体">&nbsp;</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">[DllImport(&#8220;user32.dll&#8221;)]<br />external&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;LockWindowUpdate(&nbsp;IntPtr&nbsp;hWndLock&nbsp;);<br /></span></div>
<p style="text-indent: 21pt"></span>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个函数能允许或禁止指定窗体的绘制操作，在任何时刻，整个操作系统中只能有一个窗体的绘图操作被禁止掉。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个函数的参数是窗体句柄，若参数为</span>0<span style="font-family: 宋体">表示用户界面被锁定的窗体重新释放而能绘制用户界面。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">只要在控件发生滚动时程序调用</span>LockWindowUpdate<span style="font-family: 宋体">函数，则控件的内容被锁定了，不能反映任何图形操作，</span>Windows<span style="font-family: 宋体">默认的滚动图形的操作就没有效果。当控件的滚动操作完成调用</span>LockWindowUpdate<span style="font-family: 宋体">函数来重新释放窗体并强制重新绘制控件的所有内容，则就能实现固定背景的效果。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">根据上述分析，笔者只要处理控件的滚动事件，当控件内容发生滚动时调用</span>LockWindowUpdate<span style="font-family: 宋体">函数锁定控件用户界面，而滚动完毕后又调用</span>LockWindowUpdate<span style="font-family: 宋体">函数解除锁定并重新绘制控件所有的内容则就可以让控件发送滚动时不背景图片不随之滚动。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在</span>WinForm.NET2.0<span style="font-family: 宋体">中，支持滚动的控件都是从</span>System.Windows.Forms.ScrollableControl<span style="font-family: 宋体">派生的，这些控件都提供一个</span>Scroll<span style="font-family: 宋体">事件。这个事件的参数是一个</span>System.Windows.Forms.ScrollEventArgs<span style="font-family: 宋体">类型的对象，该参数有一个</span>Type<span style="font-family: 宋体">属性值，是</span>System.Windows.Forms.ScrollEventType<span style="font-family: 宋体">类型，用于表示滚动事件的类型。</span>WinForm.NET2.0<span style="font-family: 宋体">中支持的滚动事件类型有以下几种。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt;background: #f3f3f3; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p><span style="font-family: 宋体">滚动事件类型</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt;background: #f3f3f3; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">说明</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>SmallDecrement</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框移动了较短的距离。用户单击了左（水平）或上（垂直）滚动箭头，或者按了向上键。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>SmallIncrement</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框移动了较短的距离。用户单击了右（水平）或下（垂直）滚动箭头，或者按了向下键。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>LargeDecrement</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框移动了较长的距离。用户在滚动条上单击了滚动框左侧（水平）或上方（垂直），或者按了</span> Page Up <span style="font-family: 宋体">键。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>LargeIncrement</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框移动了较长的距离。用户在滚动条上单击了滚动框右侧（水平）或下方（垂直），或者按了</span> Page Down <span style="font-family: 宋体">键。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>ThumbPosition</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框被移动。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>ThumbTrack</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框当前正在移动。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>First</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框被移动到</span> System.Windows.Forms.ScrollBar.Minimum <span style="font-family: 宋体">位置。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>Last</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框被移动到</span> System.Windows.Forms.ScrollBar.Maximum <span style="font-family: 宋体">位置。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 104.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="139">
<p>EndScroll</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 321.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="429">
<p><span style="font-family: 宋体">滚动框已停止移动。</span></p></td></tr></table></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一般的用户在进行滚动操作时会触发一个或多个不同类型的滚动事件，而且这些事件的发生过程和</span>Windows<span style="font-family: 宋体">操作系统的&#8220;拖动时显示窗口内容&#8221;设置有关。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者在控制面板中运行&#8220;显示&#8221;项目，显示出&#8220;显示属性&#8221;对话框，切换到&#8220;外观&#8221;标签页，点击&#8220;效果&#8221;按钮，弹出的&#8220;效果&#8221;对话框中就能设置&#8220;拖动时显示窗口内容&#8221;的操作系统配置项了。这个选项对控件的滚动行为影响很大。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg005.jpg" width="532" height="470" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在</span>Windows<span style="font-family: 宋体">操作系统中，鼠标右击控件的滚动条，通常会弹出如下的快捷菜单。点击这些快捷菜单就会设置滚动条的位置，而且会触发不同类型的滚动事件</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg006.jpg" width="397" height="343" /></span></p>
<p style="text-indent: 21pt"></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">经过试验，在</span>WindowsXP SP2<span style="font-family: 宋体">的环境下，点击这些菜单项目而触发的滚动事件有</span></p>
<p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">滚动至此</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p><span style="font-family: 宋体">当</span>Windows<span style="font-family: 宋体">系统设置了&#8220;拖动时显示窗口内容&#8221;时</span></p>
<p>ThumbTrack</p>
<p>ThumbPosition</p>
<p>ThumbTrack</p>
<p>ThumbPosition</p>
<p><span style="font-family: 宋体">当没有设置&#8220;拖动时显示窗口内容&#8221;时</span></p>
<p>ThumbTrack</p>
<p>ThumbTrack</p>
<p>ThumbPosition</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">顶部</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p>First 0</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">底部</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p>Last</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">向上翻页</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p>LargeDecrement</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">向下翻页</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p>LargeIncrement</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">向上滚动</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p>SmallDecrment</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 86.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="115">
<p><span style="font-family: 宋体">向下滚动</span></p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 339.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="453">
<p>SmallIncrement</p></td></tr></table></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当用户用鼠标拖拽操作直接拖动滚动条时，控件触发的滚动事件过程如下：</span></p>
<p style="text-indent: -18pt; margin: 0cm 0cm 0pt 18pt"><span>1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当用户在滚动条上按下鼠标左键，开始拖拽在时，控件触发</span>ThumbTrack<span style="font-family: 宋体">类型的滚动事件。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p style="text-indent: -18pt; margin: 0cm 0cm 0pt 18pt"><span>2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当用户移动鼠标时，每一移动都会让控件触发</span>ThumbTrack<span style="font-family: 宋体">类型的滚动事件。当</span>Windows<span style="font-family: 宋体">系统设置了&#8220;拖动时显示窗口内容&#8221;时，还会触发控件重绘事件，当没有设置&#8220;拖动时显示窗口内容&#8221;时不会触发控件重绘事件。</span></p>
<p style="text-indent: -18pt; margin: 0cm 0cm 0pt 18pt"><span>3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">当用户松开鼠标按键，结束拖拽操作时触发</span>ThumbPosition<span style="font-family: 宋体">事件。</span></p>
<p>&nbsp;</p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">此外当程序自己使用代码设置控件的</span>AutoScrollPosition<span style="font-family: 宋体">属性来自行滚动时不会触发任何控件滚动事件，鼠标滚轮操作也不会触发滚动事件。</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">以上是在笔者的</span>WindowsXP SP2<span style="font-family: 宋体">的系统中的实验效果，相信对其他</span>Windows<span style="font-family: 宋体">操作系统也一样吧。</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">根据上述实验结果，笔者重点处理</span>ThumbTrack<span style="font-family: 宋体">和</span>ThumbPosition<span style="font-family: 宋体">类型的滚动事件，由于存在&#8220;拖动时显示窗口内容&#8221;的设置，笔者会重载处理控件的</span>Windows<span style="font-family: 宋体">消息处理方法，当</span>Windows<span style="font-family: 宋体">没有设置&#8220;拖动时显示窗口内容&#8221;时，对每一个</span>ThumbTrack<span style="font-family: 宋体">事件消息都额外的处理一个</span>ThumbPosition<span style="font-family: 宋体">消息，这样就将两种情况统一起来。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p><strong><span style="font-family: 宋体; font-size: 22pt">解决问题</span></strong><strong></strong></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">根据所上述分析，笔者开始创建一种固定背景的可滚动的控件了，原理上面讲的比较清楚，因此编写代码时不再多说了。笔者首先使用</span>VS.NET2005<span style="font-family: 宋体">建立一个名为&#8220;</span>FixedBackground<span style="font-family: 宋体">&#8221;的</span>WinForm<span style="font-family: 宋体">的</span>C#<span style="font-family: 宋体">工程。然后创建一个名为</span>FixedBackgroundControl<span style="font-family: 宋体">的类型，该类型是从</span>System.Windows.Forms.UserControl<span style="font-family: 宋体">类型派生的。</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">笔者建立一个</span>FixedBackground<span style="font-family: 宋体">的属性用于指定是否启动固定背景的功能，其代码如下</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体"></span><span style="font-family: 宋体">&nbsp;</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;bolFixedBackground&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;固定背景<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">[System.ComponentModel.Category(</span><span style="color: #800000">"</span><span style="color: #800000">Appearance</span><span style="color: #800000">"</span><span style="color: #000000">)]<br />[System.ComponentModel.DefaultValue(</span><span style="color: #0000ff">false</span><span style="color: #000000">)]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;FixedBackground<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;bolFixedBackground;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bolFixedBackground&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p style="text-indent: 18pt"></span>&nbsp;</p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">然后定义一个名为</span>LogonImage<span style="font-family: 宋体">的属性用于设置在控件客户区右下角显示的图标，其代码如下</span><span style="font-family: 宋体"></p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;System.Drawing.Image&nbsp;myLogonImage&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;标志图片<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">[System.ComponentModel.Category(</span><span style="color: #800000">"</span><span style="color: #800000">Appearance</span><span style="color: #800000">"</span><span style="color: #000000">)]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;System.Drawing.Image&nbsp;LogonImage<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;myLogonImage;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myLogonImage&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p style="text-indent: 18pt">然后笔者重载控件的</span>OnPaintBackground<span style="font-family: 宋体">方法用于自定义绘制背景，其代码如下。</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体"></span><span style="font-family: 宋体">&nbsp;</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;自定义绘制控件背景<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="e"&gt;&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;OnPaintBackground(PaintEventArgs&nbsp;e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.OnPaintBackground(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(myLogonImage&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;在控件客户区的右下角绘制标志图片</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ClientSize.Width&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;myLogonImage.Width;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;y&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ClientSize.Height&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;myLogonImage.Height;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(e.ClipRectangle.IntersectsWith(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Rectangle(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myLogonImage.Width,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myLogonImage.Height)))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.Graphics.DrawImage(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myLogonImage,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;y,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myLogonImage.Width&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myLogonImage.Height&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p style="text-indent: 18pt">接着要处理控件的滚动事件了，首先笔者导入</span>Win32API<span style="font-family: 宋体">函数</span>LockWindowUpdate<span style="font-family: 宋体">，其代码如下</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体"></span><span style="font-family: 宋体">&nbsp;</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">[System.Runtime.InteropServices.DllImport(</span><span style="color: #800000">"</span><span style="color: #800000">user32.dll</span><span style="color: #800000">"</span><span style="color: #000000">)]<br /></span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">extern</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;LockWindowUpdate(IntPtr&nbsp;hWnd);</span></div>
<p style="text-indent: 18pt">笔者重载控件的</span>OnScroll<span style="font-family: 宋体">方法，其代码如下</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体"></span><span style="font-family: 宋体">&nbsp;</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;处理滚动条事件<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="se"&gt;</span><span style="color: #008000">事件参数</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;OnScroll(ScrollEventArgs&nbsp;se)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(bolFixedBackground)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;执行固定背景的操作</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(se.Type&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;ScrollEventType.ThumbTrack)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若滚动框正在移动，解除对控件用户界面的锁定</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LockWindowUpdate(IntPtr.Zero);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;立即重新绘制控件所有的用户界面</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Refresh();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;锁定控件的用户界面</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LockWindowUpdate(</span><span style="color: #0000ff">this</span><span style="color: #000000">.Handle);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;解除对控件用户界面的锁定</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LockWindowUpdate(IntPtr.Zero);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;声明控件的所有的内容无效，但不立即重新绘制</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Invalidate();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.OnScroll(se);<br />}</span></div>
<p style="text-indent: 18pt">在这里可以看到程序处理滚动事件时调用了</span>Refresh<span style="font-family: 宋体">或</span>Invalidate<span style="font-family: 宋体">函数，这将导致控件所有的内容都重新绘制，当控件比较大，内容比较复杂时会导致绘制控件图形的任务很重，从而导致明显的闪烁，这是不可避免的难于优化的过程，因此笔者使用双缓冲技术来解决闪烁文件，笔者在控件的构造函数中添加以下代码即可启用控件的双缓冲设置</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;固定背景图片会不可避免的导致闪烁，此处启用双缓冲功能。</span><span style="color: #008000"><br /></span><span style="color: #0000ff">this</span><span style="color: #000000">.DoubleBuffered&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;</span></div>
<p style="text-indent: 18pt"></span><span style="font-family: 宋体">双缓冲能避免闪烁，但拖累的软件的性能，因此本控件是一个为了美观而降低性能的典型，因此建议本技术不要大量采用。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">接着笔者要重载控件的</span>Windows<span style="font-family: 宋体">消息处理方法了，由于要事先知道</span>Windows<span style="font-family: 宋体">操作系统的&#8220;拖动时显示窗口内容&#8221;的设置。因此使用了下述代码</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;Windows操作系统是否设置为拖动时显示窗口内容<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;bolDragFullWindows&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br /><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;当创建控件Windows句柄时的处理，调用SystemParametersInfoGetBool&nbsp;API函数<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;判断操作系统是否设置为拖动时显示窗口内容。<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="e"&gt;</span><span style="color: #008000">参数</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;OnHandleCreated(EventArgs&nbsp;e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;bolDragFullWindows&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(SystemParametersInfoGetBool(SPI_GETDRAGFULLWINDOWS,&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;bolDragFullWindows,&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bolDragFullWindows&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.OnHandleCreated(e);<br />}<br /><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;SPI_GETDRAGFULLWINDOWS&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">0x0026</span><span style="color: #000000">;<br /><br />[System.Runtime.InteropServices.DllImport(<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">user32.dll</span><span style="color: #800000">"</span><span style="color: #000000">,<br />&nbsp;&nbsp;&nbsp;&nbsp;EntryPoint&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SystemParametersInfo</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;SetLastError&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">)]<br /></span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">extern</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;SystemParametersInfoGetBool(<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;action,<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">uint</span><span style="color: #000000">&nbsp;param,<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;vparam,<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">uint</span><span style="color: #000000">&nbsp;init);&nbsp;</span></div>
<p style="text-indent: 18pt"></span><span style="font-family: 宋体">在这段代码中，</span>bolDragFullWindows<span style="font-family: 宋体">全局变量用于指明是否系统是否启用了&#8220;拖动时显示窗口内容&#8221;。笔者重载了</span>OnHandleCreated<span style="font-family: 宋体">方法，在这个方法中调用</span>Win32API<span style="font-family: 宋体">函数</span>SystemParametersInfoGetBool<span style="font-family: 宋体">来获得这个系统级设置。</span></p>
<p style="text-indent: 18pt">SystemParametersInfo<span style="font-family: 宋体">函数是一个很强大的</span>Win32API<span style="font-family: 宋体">函数，用于获得各种操作系统级设置，能实现的功能点很多，具体可参考</span>MSDN<span style="font-family: 宋体">中关于该函数的详细说明。</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">经过试验，控件在创建后修改了&#8220;滚动时显示窗口内容&#8221;后，对控件的滚动行为没有发生任何影响。因此实时的检测&#8220;滚动时显示窗口内容&#8221;的设置是不合适的，应当在控件句柄创建时才检查该设置，因此笔者重载了控件的</span>OnHandleCreated<span style="font-family: 宋体">函数来检测该系统级设置并保存在一个全局变量中。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">笔者重载了控件的</span>WndProc<span style="font-family: 宋体">方法来处理控件接受的</span>Windows<span style="font-family: 宋体">底层消息，其代码如下</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;处理底层Windows消息处理方法<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="m"&gt;</span><span style="color: #008000">Windows消息对象</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;WndProc(</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;Message&nbsp;m)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(bolFixedBackground)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(m.HWnd&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Handle)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;当前消息是横向滚动条或纵向滚动条事件</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(m.Msg&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">0x0114</span><span style="color: #000000">&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;WM_HSCROLL&nbsp;</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;m.Msg&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">0x0115</span><span style="color: #000000">)</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;WM_VSCROLL&nbsp;)</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;v&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;m.WParam.ToInt32();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;((v&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">0xf</span><span style="color: #000000">)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">5</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;滚动消息是&nbsp;THUMBTRACK&nbsp;类型</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.WndProc(</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;m);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(bolDragFullWindows&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Windows操作系统没有设置为拖动时显示窗口内容<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;则重复执行&nbsp;THUMBPOSITION&nbsp;类型的滚动消息</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;v&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;v&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m.WParam&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;IntPtr(v);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.WndProc(</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;m);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.WndProc(</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;m);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.WndProc(</span><span style="color: #0000ff">ref</span><span style="color: #000000">&nbsp;m);<br />}</span></div>
<p style="text-indent: 18pt"></span><span style="font-family: 宋体">在这段代码中，若消息类型是</span>ThumbTrack<span style="font-family: 宋体">类型的滚动消息，则执行控件的默认处理方法，然后将消息类型修改为</span>ThumbPosition<span style="font-family: 宋体">类型的滚动消息，然后再次执行控件默认的消息处理方法，这样就使得控件每接受到一个</span>ThumbTrack<span style="font-family: 宋体">类型的滚动消息就处理了</span>ThumbTrack<span style="font-family: 宋体">和</span>ThumbPosition<span style="font-family: 宋体">两个消息。这就统一了有和没有&#8220;拖动时显示窗口内容&#8221;两种情况。</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">由于用户进行鼠标滚轮操作时不会触发滚动事件，因此还需要处理控件的鼠标滚轮事件来，其代码如下</p>
<div class="cnblogs_code"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;处理鼠标滚轮事件<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="e"&gt;&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;OnMouseWheel(MouseEventArgs&nbsp;e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(bolFixedBackground)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LockWindowUpdate(</span><span style="color: #0000ff">this</span><span style="color: #000000">.Handle);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.OnMouseWheel(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LockWindowUpdate(IntPtr.Zero);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Invalidate();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.OnMouseWheel(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p style="text-indent: 18pt"></span><span style="font-family: 宋体">笔者还进行了一些其他非关键的代码的编写，这样，一个具有固定背景图片的可滚动的控件开发完毕。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p><strong><span style="font-family: 宋体; font-size: 22pt">测试</span></strong><strong></strong></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体">这个控件开发完毕后，笔者就可以测试了。笔者在项目中新增一个窗体，打开窗体设计器，可以在工具箱上看到&#8220;</span>FixedBackgroundControl<span style="font-family: 宋体">&#8221;的项目，笔者点击该项目即可在窗体上画出一个固定背景图片的控件，则窗体的设计样式如下图所示</span></p>
<p style="text-indent: 18pt"><span style="font-family: 宋体"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg007.jpg" width="550" height="401" /></span></p>
<p>&nbsp;</p>
<p><span style="font-family: 宋体">笔者对该控件进行以下属性设置</span></p>
<p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 122.4pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="163">
<p>AutoScroll</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 303.7pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="405">
<p>True</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 122.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="163">
<p>AutoScrollMinSize</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 303.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="405">
<p>2000,2000</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 122.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="163">
<p>FixedBackground</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 303.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="405">
<p>True</p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 122.4pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="163">
<p>LogonImage</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: #ece9d8; padding-bottom: 0cm; background-color: transparent; padding-left: 5.4pt; width: 303.7pt; padding-right: 5.4pt; border-top: #ece9d8; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="405">
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/fixbg008.gif" width="154" height="81" /></p></td></tr></table></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这样笔者就可以运行这个窗体来检查控件的运行时效果了。</span>[<span style="font-family: 宋体">作者袁永福</span> <a href="http://www.xdesigner.cn/" target="_blank">http://www.xdesigner.cn/</a> ]</p>
<p><strong><span style="font-family: 宋体; font-size: 22pt">小结</span></strong><strong></strong></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这篇文章中，笔者使用了</span>WinForm.NET2.0<span style="font-family: 宋体">来实现一个具有固定背景图片的带滚动的控件，从而实现了类似&#8220;</span>background-attachment:fixed<span style="font-family: 宋体">&#8221;的</span>CSS<span style="font-family: 宋体">样式的用户界面，这个过程是比较复杂的，需要了解</span>WIN32<span style="font-family: 宋体">编程的一些知识。相对于常规</span>ASP.NET<span style="font-family: 宋体">开发，</span>C#<span style="font-family: 宋体">图形编程比较复杂的，应用广泛，对于软件技术爱好者来说是一片广阔的天空。</span></p>
<p>&nbsp;</p><img src="http://www.cnblogs.com/xdesigner/aggbug/1599280.html?type=1" width="1" height="1" alt=""/><p>评论: 8　<a href="http://www.cnblogs.com/xdesigner/archive/2009/11/09/fixed-background-control.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/11/09/fixed-background-control.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>我2009年10月1号过国庆感言</title><link>http://www.cnblogs.com/xdesigner/archive/2009/10/13/1582185.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Tue, 13 Oct 2009 00:44:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/10/13/1582185.html</guid><description><![CDATA[<p>阅读: 194 评论: 1 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-10-13 08:44 <a href="http://www.cnblogs.com/xdesigner/archive/2009/10/13/1582185.html" target="_blank">原文链接</a></p><p style="text-indent: 21pt"><span style="font-family: 宋体">今天是</span>2009<span style="font-family: 宋体">年</span>10<span style="font-family: 宋体">月</span>1<span style="font-family: 宋体">号，上午看了国庆阅兵式，晚上看了国庆晚会，感触比较大，祖国万岁，大中华万岁。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">国庆阅兵式上，大批军人踏着整齐的方步走过天安门前，整齐划一，绝无例外，展示了强悍的执行力，强悍的执行力就是战力逆天的精神基础。中国军队大量的现役装备展示在世人面前，成批量成系列的先进装备列装军队，最后那群桶装核导弹一看就很好很强大，这样的装备构建了完整的武器功能链，形成战力逆天的物质基础。如此强大的精神基础和物质基础就造就了战力逆天的中国军队，成就中国强大的武力。就像没人敢欺负李连杰一样，没有国家敢欺负拥有强大武力的中国。强大的武力加上和平的心就能造就稳定的和平，缺一不可。而只有稳定的和平才能使我们安心的保稳定设促发展。【</span>http://www.xdesigner.cn<span style="font-family: 宋体">】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">人际社会还多少讲究礼尚往来和广泛的尊重他人。但我看当今国际社会并无多少礼尚往来，都是讲究实力和利益交易。&#8220;韬光养晦&#8221;是前一段时期的中国对外策略，结果形成了中国的较为和平的国际环境。但这种低调形成的和平是不稳定的，现在是到了武装威慑力量来加强和延续和平的时候了。我觉得中国不必对周边小国家的小动作反应过大，中国发展的重要瓶颈只有台湾问题，我们应当集中精力解决台湾问题，等台湾问题解决了，一切就海阔天空。【</span>http://www.xdesigner.cn<span style="font-family: 宋体">】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">晚上看了国庆联欢晚会，听说是老谋子导演的，还是比较精彩的，但觉得和奥运会的开幕式提高不是很多，呵呵，现在的观众都学我们的客户，越来越挑剔了。那个和平鸽形状的烟花比奥运那个大脚印的图形复杂了许多，想必这一年那些烟火师傅改进了不少。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">改革开发是正确的路线，没有改革开发，中国怕是像现在的朝鲜一样，绝无前途。纵然改革开发带来了很多问题，但世界上没有绝对正面的事物，些许问题最终都是可以解决的，但改革开发带来的利益是巨大的本质的。回想小时候去外婆家，起大早坐车，下午才能到，而现在只要</span>2<span style="font-family: 宋体">个小时。以前打电话很麻烦，长途都得靠电报，现在手机很方便，</span>3G<span style="font-family: 宋体">上网也很方便。【</span>http://www.xdesigner.cn<span style="font-family: 宋体">】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一个国家真正的强大是综合的强大，军队强大，办的联欢会强大，铁路修到了青藏高原，强大，开始在国外办孔子学院，文化正在强大。没有综合的强大就没有生存权，没有综合的强大就没有和平和发展。我作为一名软件从业者，认为中国的综合的强大包括计算机软件业的强大，国家该花精力认真抓盗版了，因为盗版对中国软件业是釜底抽薪的伤害。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">最后祝福祖国繁荣昌盛，祝各位节日吃好喝好玩好，多为祖国的建设出点力啊。</span></p><img src="http://www.cnblogs.com/xdesigner/aggbug/1582185.html?type=1" width="1" height="1" alt=""/><p>评论: 1　<a href="http://www.cnblogs.com/xdesigner/archive/2009/10/13/1582185.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/10/13/1582185.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>C#发现之旅 - 高性能ASP.NET树状列表控件</title><link>http://www.cnblogs.com/xdesigner/archive/2009/09/20/asp_net_treeview.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Sun, 20 Sep 2009 09:37:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/09/20/asp_net_treeview.html</guid><description><![CDATA[<p>阅读: 1165 评论: 9 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-09-20 17:37 <a href="http://www.cnblogs.com/xdesigner/archive/2009/09/20/asp_net_treeview.html" target="_blank">原文链接</a></p><h1><font size="+0">C#发现之旅 - </font><span>高性能</span>ASP.NET<span>树状列表控件</span></h1>
<h2><span style="font-family: 黑体">本章介绍</span></h2>
<p><span>本课程研究了使用</span>XSLT<span>技术来开发一个树状列表</span>WEB<span>控件，展示了</span>XSTL<span>的一些高级应用，以及</span>ASP.NET<span>控件的开发过程，本课程内容比较多。本章的配套演示程序为<a href="http://files.cnblogs.com/xdesigner/ASPNETTreeView.zip">http://files.cnblogs.com/xdesigner/ASPNETTreeView.zip</a></span><span>。</span></p>
<h2><span style="font-family: 黑体">已有树状列表控件分析</span></h2>
<h3><span>发现问题</span></h3>
<p><span>近期发现有人在</span>ASP.NET<span>项目开发中使用一种叫</span>dtree<span>的树状列表组件加载缓慢。这也是笔者撰写本章的动机。毛主席教导我们，做事要发现问题，分析问题和解决问题。首先我们发现了已有的树状列表</span>WEB<span>控件加载缓慢的问题，接下来就很自然的是分析问题了。</span></p>
<p><span>下图就是</span>dtree <span>运行界面的例子<span>【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>)】</span></span></p>
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage001.jpg" width="482" height="412" /></p>
<h3><span>分析问题</span></h3>
<p><span>现在我们分析问题，对使用</span>dtree<span>生成树状列表的程序代码的分析，可以了解程序运行过程如下图所示</span></p>
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage002.gif" width="626" height="406" /></p>
<p><span>在这样的程序中，首先服务器端的</span>C#<span>代码查询数据库，然后根据查询所得数据拼凑出一个</span>JavaScript<span>代码字符串，然后发往客户端，客户端浏览器获得这个</span>JavaScript<span>代码字符串并开始执行它，而在</span>JavaScript<span>脚本中也是字符串拼凑出一段</span>HTML<span>代码字符串，然后使用浏览器提供的</span>document.write<span>方法或</span>obj.innerHTML<span>属性将生成的</span>HTML<span>字符串填充到</span>HTML<span>页面中进行展示。</span></p>
<p><span>这是是分析了</span>dtree<span>的流程，但使用其他的一些树状列表控件也大体如此。</span></p>
<p><span>现在我们根据这个流程图来判断是哪个环节速度缓慢。基本上数据库本身查询速度是没问题；将查询结果传递到</span>C#<span>程序中问题也不大，因为一般的数据库服务器和</span>ASP.NET<span>程序是在一台电脑上或者同一个高速局域网中；</span>C#<span>程序生成</span>JavaScript<span>字符串的过程也是没多大问题，因为</span>C#<span>运行速度是相当的快的，而且还有</span>StringBuilder<span>来加速字符串拼凑操作，因此只要逻辑算法没有问题，速度是有保障的。总体来说服务器端内部是没有速度问题。</span></p>
<p><span>将</span>JavaScript<span>字符串通过网络从服务器端发送到客户端，所花的的时间是字符串长度除以网络传输速度，若</span>WEB<span>系统运行在高速的局域网中，则速度没多大问题，但若</span>WEB<span>程序运行在缓慢的广域网或英特网中，则</span>JavaScript<span>字符串长度会比较大的影响程序运行速度。由于公司系统主要运行在局域网中，因此网络传输速度不是主要问题。</span></p>
<p><span>在客户端浏览器中，浏览器接受并执行</span>JavaScript<span>脚本代码，在</span>JavaScript<span>脚本中使用字符串拼凑来生成用于展现树状列表的</span>HTML<span>字符串。</span>JavaScript<span>代码是解释方式执行的，速度相当慢，而字符串拼凑操作也是比较缓慢的操作，</span>JavaScript<span>中没有任何手段来优化字符串拼凑操作。因此由</span>JavaScript<span>代码生成</span>HTML<span>字符串的过程是缓慢的，这是一个速度瓶颈。</span></p>
<p>JavaScript<span>代码还调用浏览器提供的</span>document.write<span>函数或</span>innerHTML<span>属性将生成的</span>HTML<span>字符串填充到页面中，浏览器会解析这个</span>HTML<span>代码并展现出树状列表。由于</span>document.write<span>或</span>innerHTML<span>是运行在浏览器内部的，外部程序无法控制，而且速度也不算慢，因此这里也就没有什么好优化的。</span></p>
<p><span>经过上述分析，可以看到整个展现树状列表的过程中最缓慢的环节就是使用</span>JavaScript<span>脚本来生成</span>HTML<span>代码字符串，其次就是数据从服务器端发送到客户端的过程。若一个树状列表要显示数千个节点，则</span>JavaScript<span>脚本将拼凑出几百</span>K<span>甚至过</span>MB<span>的</span>HTML<span>字符串，这个过程是相当缓慢的，很容易导致</span>IE<span>浏览器由于脚本运行过于缓慢而提示用户是否继续执行脚本。</span></p>
<p><span>因此</span>JavaScript<span>脚本生成</span>HTML<span>字符串将是我们主要的优化环节，也是新开发的树状列表控件的重点关注部分。</span></p>
<h3><span>解决问题</span></h3>
<p><span>经过上述分析，我们可以了解到树状列表加载缓慢主要原因就是</span>JavaScript<span>脚本生成</span>HTML<span>字符串过程缓慢，很自然我们就针对这个原因来解决问题。</span></p>
<p><span>【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>)】首先我们可以完全抛弃</span>JavaScript<span>脚本，使用</span>C#<span>在服务器端生成</span> <span>展现树状列表的</span>HTML<span>代码，然后发往客户端</span> <span>，客户端浏览器获得</span>HTML<span>代码并展示出树状列表。</span></p>
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage003.gif" width="623" height="406" /></p>
<p><span>在这种模式下，</span> <span>服务器端的</span>C#<span>程序查询数据库获得数据，并使用字符串拼凑来生成用于展现树状列表的</span>HTML<span>代码，由于</span>C#<span>功能强大，而且速度比较快，可以使用</span>StringBuilder<span>来加速字符串拼凑操作，而客户端浏览器获得的这个</span>HTML<span>代码，立即解析并显示出树状列表。因此整个过程是相当快的。这是一个可以采用的解决方法。</span></p>
<p><span>当然这个方式有一定的限制性，若服务器程序运行也比较缓慢，比如</span>ASP<span>，它比客户端的</span>JavaScript<span>脚本快不了很多，此时这种方法优势就不明显了。</span></p>
<p>【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】&nbsp;</p>
<p><span>另外一个方法就是加速</span>JavaScript<span>脚本生成</span>HTML<span>代码的过程。这时我们可以考虑使用其他的可快速运行的程序来辅助</span>JavaScript<span>来生成</span>HTML<span>代码，于是我们想到</span>COM<span>组件，我们可以设计出这样的程序结构。</span></p>
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage004.gif" width="626" height="406" /></p>
<p><span>在这个软件结构中，</span>C#<span>程序连接数据库查询数据，然后生成</span>JavaScript<span>脚本字符串，而客户端浏览器获得并执行</span>JavaScript<span>脚本，在</span>JavaScript<span>脚本调用外部的</span>COM<span>组件，生成</span>HTML<span>字符串，然后使用</span>document.write<span>或</span>innerHTML<span>将</span>HTML<span>字符串填充到页面中显示出树状结构。由于</span>COM<span>组件一般是用</span>C++<span>等编译性语言开发的，因此运行速度比</span>JavaScript<span>快得多，这样能加速</span>JavaScript<span>生成</span>HTML<span>代码的速度。</span></p>
<p><span>由于便于</span>B/S<span>系统的开发和部署，我们尽量避免自己开发的</span>COM<span>组件或使用第三方组件，而是使用</span>Windows<span>操作系统自带的标准</span>COM<span>组件，浏览器认为该组件比较安全，运行速度快，而且还能方便的生成</span>HTML<span>字符串。这个组件是什么呢？这就是</span>MSXML<span>组件。</span></p>
<p>MSXML<span>组件是用</span>C++<span>开发的，是</span>Windows<span>操作系统的标准部分，而且是</span>IE<span>浏览器认为比较安全的</span>ActiveX<span>组件，能和</span>IE<span>浏览器进行密切的协作。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p><span>那么我们又如何使用</span>MSXML<span>组件来生成</span>HTML<span>代码呢？我们可以采用</span>XSLT<span>技术，首先系统提供一个</span>XML<span>文档，该文档定义了树状结构信息，然后我们调用一个事先定义好的</span>XSLT<span>文档，将两者进行</span>XSLT<span>转化，一下子就能生成</span>HTML<span>字符串，然后将生成的</span>HTML<span>字符串填充到页面中。在这个过程中，大部分运算量是由</span>MSXML<span>完成，而</span>MSXML<span>组件是用</span>C++<span>开发的，运行速度快，这样就能大大加快整个生成</span>HTML<span>字符串的过程，从而加快树状列表的加载过程。</span></p>
<p><span>由于</span>XSLT<span>是国际标准，因为我们在服务器端也可以使用这种方法。而且客户端和服务器端的代码类似，因此我们有可能开发出同时支持服务器端运行和客户端运行的树状列表</span>WEB<span>控件。</span></p>
<h2><span style="font-family: 黑体">运行软件</span></h2>
<p><span>笔者已经根据上述的解决问题的方式经过上述的软件设计开发出了这个树状列表</span>WEB<span>控件，并编写了演示页面，现对该控件的功能进行展示，使得读者对这个控件有一些初步的印象。打开浏览器直接输入演示页面地址，打开页面，可以看到如下的用户界面【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage005.jpg" /></p>
<p><span>可以看到页面上主要显示了两个树状列表，其显示内容都是按照客户，定单，货物三层结构的树状列表。其中左边的树状列表是一次性加载了所有的数据，共生成</span>3072<span>个节点。而右边的列表只加载了第一层节点，共</span>91<span>个节点，但右边的列表能动态加载子节点列表。用户可以使用鼠标点击操作来展开和收缩节点，点击货物节点会显示一个消息框。</span></p>
<h2><span style="font-family: 黑体">软件设计</span></h2>
<p><span>为了便于开发人员使用，笔者开发出一个通用的树状列表</span>WEB<span>控件，该控件名称为</span>SkyTreeViewControl<span>，是一种从</span>System.Web.UI.WebControls.WebControl<span>派生的</span>WEB<span>控件，这样开发人员以后在</span>ASP.NET <span>程序中需要树状列表时只要将这个控件拖拽到页面即可开始使用了。现在开始进行控件的基本设计。</span></p>
<h3><span>结构设计</span></h3>
<p><span>根据上面分析的结果，笔者采用</span>XML/XSLT<span>技术，于是就可以设计出如下的程序运行流程。</span></p>
<p align="left"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage006.gif" width="628" height="410" /></p>
<p><span>在这个流程中，服务器的</span>C#<span>程序查询数据库获得树状结构信息，并将树状结构信息保存到一个</span>XML<span>文档中，然后发往客户端。而客户端执行的</span>JavaScript<span>脚本中，调用</span>MSXML<span>组件加载服务器端生成的节点</span>XML<span>文档，并从服务器上下载事先准备好的</span>XSLT<span>模板文档，然后调用</span>MSXML<span>组件执行</span>XSLT<span>转换，转换结果就是</span>HTML<span>字符串，然后将这个字符串填充到页面上展示出树状列表。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<h3><span>目标</span>HTML<span>代码设计</span></h3>
<p><span>无论</span>WEB<span>控件或者</span>JavaScript<span>等等经过怎样的处理，浏览器最终都是依据</span>HTML<span>代码来显示文档界面的，因此设计</span>WEB<span>控件，首先得设计</span>WEB<span>控件最终生成的</span>HTML<span>代码，也就是</span>WEB<span>控件的执行目标。</span></p>
<p><span>为了展现树状结构，业界已经设计出很多种</span>HTML<span>代码格式。有使用</span>DIV<span>标签的，有使用</span>P<span>标签的，笔者这里经过一些尝试，决定采用</span>TABLE<span>标签，使用表格套表格的方式来展现树状列表的层次结构。其设计的</span>HTML<span>页面范例如下。</span><br /><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage007.gif" width="435" height="405" /></p>
<p><span>培训演示程序中有一个名为</span>treeviewsample.htm <span>的文件，其中就是这个树状列表的</span>HTML<span>样本。</span></p>
<p><span>这个演示</span>HTML<span>文档中，展现节点&#8220;</span>10359 <span>成先生&#8221;及其子节点的</span>HTML<span>代码片段如下</span></p>
<p><span></p>
<p>&nbsp;</p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">&lt;</span><span style="color: #800000">table&nbsp;</span><span style="color: #ff0000">cellspacing</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;cellpadding</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;border</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">&nbsp;bordercolor</span><span style="color: #0000ff">="black"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="187"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;align</span><span style="color: #0000ff">="left"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;background</span><span style="color: #0000ff">="SkyTreeViewControl_line.gif"</span><span style="color: #ff0000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="NodeID_expend"</span><span style="color: #ff0000">&nbsp;src</span><span style="color: #0000ff">="SkyTreeViewControl_expend.gif"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="NodeID_icon"</span><span style="color: #ff0000">&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;src</span><span style="color: #0000ff">="SkyTreeViewControl_open.bmp"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="NodeID_text"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">10359&nbsp;成先生</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">table&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="NodeID_table"</span><span style="color: #ff0000">&nbsp;cellspacing</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;cellpadding</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;border</span><span style="color: #0000ff">="1"</span><span style="color: #ff0000">&nbsp;bordercolor</span><span style="color: #0000ff">="black"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;align</span><span style="color: #0000ff">="left"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">src</span><span style="color: #0000ff">="SkyTreeViewControl_child.gif"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;nowrap</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="IDAIL4QC_icon"</span><span style="color: #ff0000">&nbsp;src</span><span style="color: #0000ff">="SkyTreeViewControl_default.bmp"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="IDAIL4QC_text"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">饼干</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;align</span><span style="color: #0000ff">="left"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">src</span><span style="color: #0000ff">="SkyTreeViewControl_child.gif"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;nowrap</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="IDARL4QC_icon"</span><span style="color: #ff0000">&nbsp;src</span><span style="color: #0000ff">="SkyTreeViewControl_default.bmp"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="IDARL4QC_text"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">花奶酪</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;align</span><span style="color: #0000ff">="left"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">src</span><span style="color: #0000ff">="SkyTreeViewControl_lastchild.gif"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;nowrap</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="IDAWL4QC_icon"</span><span style="color: #ff0000">&nbsp;src</span><span style="color: #0000ff">="SkyTreeViewControl_default.bmp"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">="IDAWL4QC_text"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">温馨奶酪</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">table</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">table</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span></div>
<p>则这段</span>HTML<span>代码的显示效果为</span></p>
<p style="text-align: center; text-indent: 21pt" align="center"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage008.jpg" width="196" height="128" /></p>
<p><span>分析这段</span>HTML<span>代码，读者可以看到，每一个节点都占据一个表格行，节点文本后面还跟着一个</span>Table<span>来容纳子节点。如此循环则使用表格套表格的方式实现了一个树状列表结构。</span></p>
<p>HTML<span>中，对于每一个节点都定义了一个惟一的编号，比如&#8220;</span>NodeID<span>&#8221;，在实际应用中则可以是任意样式的</span>ID<span>号，而且每一个节点分成</span>4<span>个部分。首先是前面的展开收缩控制元素。用一个图片元素来表示，当节点展开时使用图标</span><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage009.gif" width="18" height="18" /><span>，当节点收缩时使用图标</span><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage010.gif" width="18" height="18" /><span>。该图片元素编号为&#8220;</span>NodeID_expend<span>&#8221;，占据了节点表格行的第一个单元格。由于树状结构有同层节点连接线，若节点不是上级节点的最后一个子节点则设置第一个单元格的背景图片来模拟显示同层节点连接线。</span></p>
<p><span>节点表格行的第二个单元格用来放置节点的图标，文本和子节点的表格。每一个节点都有一个图标，使用</span>IMG<span>元素来展示，元素编号是&#8220;</span>NodeID_icon<span>&#8221;，而且若有子节点，则节点可以展开和收缩，此时节点的图标是不同的，需要动态设置。最典型的就是节点展开时使用图标</span><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage011.jpg" width="16" height="16" /><span>，而节点收缩时使用图标</span><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage012.jpg" width="16" height="16" /><span>，当然两个图标是可以一样的。这里使用扩展属性&#8220;</span>SrcBack<span>&#8221;来设置节点第二个图标的图片地址，当节点展开或收缩时可以将图片元素的</span>SrcBack<span>属性值和标准的</span>Src<span>属性值进行互换即可实现节点图标的变化。</span></p>
<p><span>节点图标后面就是用一个</span>A<span>标签来显示节点文本了，这个元素的编号为&#8220;</span>NodeID_text<span>&#8221;。</span></p>
<p><span>若节点有子节点，则在节点文本后面放置一个</span>Table&nbsp;<span>元素来显示子节点。该表格的编号为&#8220;</span>NodeID_table<span>&#8221;。这个表格里面也是一个表格行来显示一个节点数据。当用户点击节点的展开和收缩标记时，笔者就可以编写脚步来控制容纳子节点的</span>Table<span>对象的</span>display<span>的样式值来显示或隐藏这个表格，从而实现子节点的展开和收缩。</span></p>
<p>HTML<span>代码设计后，笔者开发的</span>WEB<span>控件的最终的目标就是生成这样的</span>HTML<span>代码，其生成过程有很多种，有字符串拼凑的，有在服务器端用</span>C#<span>程序生成，也有在客户端用</span>JavaScript<span>脚本代码来生成。在这里使用</span>XSLT<span>来生成</span>HTML<span>代码，并支持在服务器端和客户端生成代码。</span></p>
<h3><span>脚本设计</span></h3>
<p><span>基本的</span>HTML<span>代码设计出来后，接着就开始设计客户端脚本，使得这个静态的树状列表具有动态的效果。这里采用</span>JavaScript<span>脚本语言，树状列表的动态效果就是用户鼠标点击某个节点时，若该节点有子节点，则设置包含子节点的表格元素在可见和不可见的状态的切换，而且同时更新元素的图标来表示节点的展开收缩状态，此外还设置节点的文本为高亮度显示来表示该节点处于选择状态。</span></p>
<p><span>读者知道</span>HTML<span>的</span>CSS<span>样式控制中有一个名为&#8220;</span>display<span>&#8221;的样式，若设置&#8220;</span>display<span>&#8221;的值为&#8220;</span>none<span>&#8221;时则</span>HTML<span>元素不可见而且不占地方，就好像这个元素从来就没有存在过，若设置&#8220;</span>display<span>&#8221;样式为空字符串时，则</span>HTML<span>元素是正常显示。</span>JavaScript<span>脚本就可以修改子节点表格元素的&#8220;</span>display<span>&#8221;样式来显示或隐藏子节点列表。</span></p>
<p><span>在</span>JavaScript<span>中，很多</span>HTML<span>元素有&#8220;</span>getAttribute<span>&#8221;和&#8220;</span>setAttribute<span>&#8221;函数，用来读取和设置扩展属性，在上面的</span>HTML<span>设计中，笔者对显示节点图标的图片元素定义了一个名为&#8220;</span>SrcBack<span>&#8221;的非标准属性。在</span>JavaScript<span>中，可以使用代码&#8220;</span>obj.getAttribute(&#8220;SrcBack&#8221;)<span>&#8221;来获得该属性值，使用&#8220;</span>obj.setAttribute(&#8220;SrcBack&#8221;,&#8221;<span>新数据</span>&#8221;)<span>&#8221;来设置该属性值；在</span>IE<span>浏览器中，开发人员可以使用更简洁的方式，直呼其名的获得和设置扩展属性值，也就是使用&#8220;</span>obj.SrcBack<span>&#8221;属性，但这是微软对</span>JavaScript<span>和</span>HTML DOM<span>的扩展，只适用于</span>IE<span>，其他浏览器是不支持的，为了使得控件具备一定的兼容性，笔者这里使用&#8220;</span>getAttribute<span>&#8221;和&#8220;</span>setAttribute<span>&#8221;这种符合</span>HTML<span>国际标准的编程接口。</span></p>
<p><span>在脚本程序中有个很重要的问题是如何加载</span>XML<span>和</span>XSLT<span>文档。很多时候这里的</span>XML<span>文件是动态生成的，而</span>XSLT<span>文档是事先编制好的。一般的需要三个文档，一个是包容树状列表的主</span>HTML<span>页面，一个是生成</span>XML<span>文档的动态服务器页面，还有一个是保存在服务器上的静态的</span>XSLT<span>文件。这三个文件分开提供，则不利于程序的编写和部署，为此这里采用微软</span>IE<span>浏览器所特有的</span>XML<span>数据岛（</span>XML Island<span>）的功能，将</span>XML<span>文档和</span>XSLT<span>文档嵌入到</span>HTML<span>文档中，从而仅仅依赖一个</span>HTML<span>文档即可生成树状列表。</span></p>
<p><span>在</span>HTML<span>中使用标签</span>XML<span>来定义一个</span>XML<span>数据岛元素。其范例为</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">&lt;</span><span style="color: #800000">XML&nbsp;</span><span style="color: #ff0000">ID</span><span style="color: #0000ff">="XMLIslandID"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">METADATA</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">AUTHOR</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">John&nbsp;Smith</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">AUTHOR</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">GENERATOR</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Visual&nbsp;Notepad</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">GENERATOR</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">PAGETYPE</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Reference</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">PAGETYPE</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">ABSTRACT</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">Specifies&nbsp;a&nbsp;data&nbsp;island</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">ABSTRACT</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">METADATA</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">XML</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span></div>
<p>开发人员既可以使用它的</span>src<span>属性来指定动态加载的</span>XML<span>文档的</span>URL<span>地址，也可以直接在</span>XML<span>标签之间填写</span>XML<span>代码。在</span>JavaScript<span>中，开发人员可以使用</span>XML<span>数据岛对象的</span>XMLDocument<span>属性来获得</span>XML<span>文档对象，也就是调用&#8220;</span>XMLIslandID.XMLDocument<span>&#8221;语句，开发人员还可以使用响应它的&#8220;</span>onreadystatechange<span>&#8221;事件来执行该</span>XML<span>数据加载完毕后的处理。</span></p>
<p>XML<span>数据岛是</span>IE<span>浏览器的特有的功能，其他浏览器不支持</span>XML<span>数据岛。关于</span>XML<span>数据岛的详细信息可参考</span>MSDN<span>中的相关说明。若要使得控件能在多个浏览器中运行，则不得使用</span>XML<span>数据岛。此处为了开发方便就采用</span>XML<span>数据岛技术，不过这使得控件只能用于</span>IE<span>浏览器。</span></p>
<h3><span>节点</span>XML<span>文档设计</span></h3>
<p><span>在这个</span>WEB<span>控件中将采用</span>XML/XSLT<span>技术来生成</span>HTML<span>代码。首先得设计出定义树状结构的</span>XML<span>文档，由于</span>XML<span>文档本身是树状结构，因此这里的</span>XML<span>文档设计就比较简单的了。大家可以提出很多种设计方案，在此我提出如下的设计方案。先看一下</span>XML<span>文档的范例。</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="utf-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">RootNodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">customer.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">艾德高科技</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">order.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">10359&nbsp;成先生</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">product.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">饼干</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">OnClick</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">alert('饼干')</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">OnClick</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">product.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">温馨奶酪</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">OnClick</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">alert('温馨奶酪')</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">OnClick</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">customer.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">霸力建设</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">order.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">10858&nbsp;余小姐</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">product.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Icon</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">海鲜粉</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">OnClick</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">alert('海鲜粉')</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">OnClick</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">Nodes&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Nodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">Node</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">RootNodes</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span></div>
<p>详细读者看到这个范例后能很容易的理解这个</span>XML<span>文档的结构，</span>Node<span>元素表示一个节点，它下面有</span>Icon<span>元素指定元素图标文件名，</span>Text<span>元素指定节点文本，</span>OnClick<span>元素指定节点的</span>OnClick<span>事件处理，</span>Nodes<span>元素用于放置子节点。根元素</span>RootNodes<span>下放置了树状列表第一层节点。</span></p>
<h3>XSLT<span>文档设计</span></h3>
<p>XSLT<span>文档是这个控件中比较复杂的部分，在后面将详细说明其内容。</span></p>
<h2><span style="font-family: 黑体">软件说明</span></h2>
<p><span>根据软件设计，笔者已经完成了该程序，程序主要包含以下几个文件</span></p>
<table style="border-bottom: medium none; border-left: medium none; width: 516.15pt; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0" width="688">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>Default.aspx</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>演示树状列表</span>WEB<span>控件的一个</span>ASPX<span>页面。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>SkyTreeNode.cs</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>定义了表示树状列表中一个节点的类型。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>SkyTreeNodeList.cs</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>定义了一种树状节点列表的类型。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>TreeViewNodeXml.aspx</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>为动态加载子节点的控件提供节点</span>XML<span>文档的服务页面。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>SkyTreeViewControl.bmp</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>控件在设计器工具箱上的图标的图片。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>SkyTreeViewControl.cs</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>控件</span>C#<span>源代码文件。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>SkyTreeViewControl.xslt</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>和控件配套使用的</span>XSLT<span>文件。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 155.6pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="207">
<p>SkyTreeViewControl_*.gif/bmp</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 360.55pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="481">
<p><span>一系列的显示树状列表结构所需的小图片。</span></p></td></tr></table>
<p><span>现对该软件进行详细说明。</span></p>
<h3>SkyTreeNode.cs</h3>
<p><span>该文件中定义了类型</span>SkyTreeNode<span>，用于表示树状列表中的一个节点，其主要代码如下</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;树状列表节点对象<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;remarks&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;本对象表示高性能ASP.NET树状列表中的一个节点,每个节点<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;有个Nodes属性用于保存子节点，由此可以形成树状结构。<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/remarks&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">[System.Serializable()]<br />[System.Xml.Serialization.XmlType(</span><span style="color: #800000">"</span><span style="color: #800000">Node</span><span style="color: #800000">"</span><span style="color: #000000">)]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;SkyTreeNode<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;初始化对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNode()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myNodes&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SkyTreeNodeList(</span><span style="color: #0000ff">this</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;节点编号<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;remarks&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;在生成HTML代码时，系统会调用XSLT的函数&nbsp;generate-id()&nbsp;来生成节点HTML<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;编号，在同一个XML文档时，自动生成的编号是唯一的不会重复。但当页面上有<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;多个树状列表或者需要客户端动态加载节点时则会在不同的XML文档上调用<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;generate-id()&nbsp;函数，这会导致节点的HTML编号重复，此时需要明确的设置该ID<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;属性以确保生成的节点的HTML编号不重复。一般可以设置为&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;System.GUID.NewGUID().ToString()&nbsp;值<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/remarks&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;ID<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strID;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strText&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;节点文本<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Text<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strText;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strText&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strIcon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;节点图标URL地址<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Icon<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strIcon;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strIcon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strLink&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;节点链接地址<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Link<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strLink;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strLink&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;节点数值<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;Value<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strValue;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strOnClick&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;节点点击事件处理代码<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;OnClick<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strOnClick;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strOnClick&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strXMLSource&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;子节点信息XML来源<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;remarks&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;当客户端要动态的加载节点的子节点，则必须要设置该属性为一个<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;相对或绝对的URL地址，该地址必须使用一个页面参数来传递该节点的<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;ID属性。<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/remarks&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;XMLSource<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strXMLSource;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strXMLSource&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;SkyTreeNode&nbsp;myParent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;父节点对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;remarks&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;Parent属性不能参与XML序列化和反序列化，否则会出现树状节点<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;循环引用而导致程序结构错误，因此使用&nbsp;XmlIgnore&nbsp;特性来说明<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;不参与XML序列化和反序列化。<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/remarks&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[System.Xml.Serialization.XmlIgnore()]<br />&nbsp;&nbsp;&nbsp;&nbsp;[System.ComponentModel.Browsable(</span><span style="color: #0000ff">false</span><span style="color: #000000">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNode&nbsp;Parent<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;myParent;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myParent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;SkyTreeNodeList&nbsp;myNodes&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;子节点列表<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;remarks&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;此处使用XmlArrayItem特性说明Nodes属性是一个列表，该列表对应<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;的XML节点下Node名称的子XML节点对应一个SkyTreeNode类型的对象。<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/remarks&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[System.Xml.Serialization.XmlArrayItem(</span><span style="color: #800000">"</span><span style="color: #800000">Node</span><span style="color: #800000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(SkyTreeNode))]<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNodeList&nbsp;Nodes<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;myNodes;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}</span><span style="color: #008000">//</span><span style="color: #008000">public&nbsp;class&nbsp;SkyTreeNode</span><span style="color: #008000"><br /></span></div>
<p>本类型比较简单，定义了一些树状节点拥有的属性，此外还定义了一个</span>Nodes<span>子节点列表，一个节点可以有若干个子节点，则多个节点组合起来就可以构成树状列表。</span></p>
<p><span>该类型前面使用代码&#8220;</span>[System.<span style="color: #154857">Serializable()]</span><span>&#8221;来指定类型可以进行二进制序列化，在</span>ASP.NET2.0<span>中，所有可以保存在页面</span>Session<span>或</span>ViewState<span>中的对象必须可以执行二进制序列化，若</span>SkyTreeNode<span>类型没有使用代码&#8220;</span>[System.<span style="color: #154857">Serializable()]</span><span>&#8221;标记为可执行二进制序列化，则不能将其保存在页面</span>Session<span>或</span>ViewState<span>中。类型</span>SkyTreeNode<span>前面还使用代码&#8220;</span>[System.Xml.Serialization.<span style="color: #154857">XmlType(<span style="color: #a31515">"Node"</span>)]</span><span>&#8221;来指定类型进行</span>XML<span>序列化时的使用的</span>XML<span>标签名为&#8220;</span>Node<span>&#8221;。</span></p>
<p><span>对&#8220;</span>Parent<span>&#8221;属性在使用代码&#8220;</span>[System.Xml.Serialization.<span style="color: #154857">XmlIgnore()]</span><span>&#8221;表明该属性不执行</span>XML<span>序列化和反序列化。由于</span>XML<span>序列化是递归处理对象的所有的可读写属性，而&#8220;</span>Parent<span>&#8221;属性指向该节点的父节点，而父节点的&#8220;</span>Nodes<span>&#8221;属性又包含了这个节点，如此形成了对象循环引用，若&#8220;</span>Parent<span>&#8221;属性参与</span>XML<span>序列化则必然会造成无限递归循环，导致程序错误。</span></p>
<h3>SkyTreeNodeList.cs</h3>
<p><span>该文件定义了</span>SkyTreeNodeList<span>类型，该类型是树状节点列表，能存储若干个树状节点对象，该类型的代码为</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;树状列表节点列表<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">[System.Serializable()]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;SkyTreeNodeList&nbsp;:&nbsp;System.Collections.CollectionBase<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;初始化对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNodeList()<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;初始化对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="node"&gt;</span><span style="color: #008000">列表所属节点对象</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNodeList(SkyTreeNode&nbsp;node)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myOwnerNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;node;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;SkyTreeNode&nbsp;myOwnerNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;拥有该列表的节点对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;[System.ComponentModel.Browsable(</span><span style="color: #0000ff">false</span><span style="color: #000000">)]<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNode&nbsp;OwnerNode<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;myOwnerNode;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;返回指定序号处的节点对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNode&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">[</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;index]<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;(SkyTreeNode)</span><span style="color: #0000ff">this</span><span style="color: #000000">.List[index];&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;向列表添加节点<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="node"&gt;</span><span style="color: #008000">节点对象</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;returns&gt;</span><span style="color: #008000">新节点在列表中的序号</span><span style="color: #808080">&lt;/returns&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;Add(SkyTreeNode&nbsp;node)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(node&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArgumentNullException(</span><span style="color: #800000">"</span><span style="color: #800000">node</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(myOwnerNode&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.Parent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myOwnerNode;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.List.Add(node);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;向列表添加若干个节点<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="nodes"&gt;</span><span style="color: #008000">节点列表,该列表中的元素类型必须为SkyTreeNode类型</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;AddRange(System.Collections.ICollection&nbsp;nodes)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(nodes&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ArgumentNullException(</span><span style="color: #800000">"</span><span style="color: #800000">nodes</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">foreach</span><span style="color: #000000">&nbsp;(SkyTreeNode&nbsp;node&nbsp;</span><span style="color: #0000ff">in</span><span style="color: #000000">&nbsp;nodes)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(myOwnerNode&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.Parent&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myOwnerNode;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.List.Add(node);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;删除节点<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="node"&gt;</span><span style="color: #008000">节点对象</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Remove(SkyTreeNode&nbsp;node)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.List.Remove(node);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;判断节点在列表中的序号<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="node"&gt;</span><span style="color: #008000">节点对象</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;returns&gt;</span><span style="color: #008000">节点在列表中的从0开始的序号，若不存在则返回-1</span><span style="color: #808080">&lt;/returns&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;IndexOf(SkyTreeNode&nbsp;node)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.List.IndexOf(node);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;判断列表是否存在指定的节点对象<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="node"&gt;</span><span style="color: #008000">节点对象</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #008000"><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;returns&gt;</span><span style="color: #008000">是否存在该节点</span><span style="color: #808080">&lt;/returns&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;Contains(SkyTreeNode&nbsp;node)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.List.Contains(node);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span><span style="color: #008000">//</span><span style="color: #008000">public&nbsp;class&nbsp;SkyTreeNodeList&nbsp;:&nbsp;System.Collections.CollectionBase</span><span style="color: #008000"><br /></span></div>
<p>本类型比较简单，它是从类型&#8220;</span>System.Collections.CollectionBase<span>&#8221;上派生的针对</span>SkyTreeNode<span>类型的强类型的列表，它使用代码&#8220;</span>[System.<span style="color: #154857">Serializable()]</span><span>&#8221;表明可以进行二进制序列化，它提供了一些属性和方法用于维护列表中的树状节点元素。</span></p>
<h3>SkyTreeViewControl.cs</h3>
<p><span>树状列表控件所有的</span>C#<span>代码就放置在这个文件中。打开这个文件，首先我们看到一条指令</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;此时对程序集使用TagPrefix特性，表示CS_Discovery名称控件下的WEB控件<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;在ASPX的HTML代码中默认使用SkyWebControl作为其HTML标签的前缀</span><span style="color: #008000"><br /></span><span style="color: #000000">[assembly:System.Web.UI.TagPrefix(</span><span style="color: #800000">"</span><span style="color: #800000">CS_Discovery</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyWebControl</span><span style="color: #800000">"</span><span style="color: #000000">)]<br /></span></div>
<p>这条指令前面有&#8220;</span>assembly:<span>&#8221;的前缀，表示这是一个针对程序集的指令，它具有两个参数，第一个参数为某个名称控件，第二个参数指定该名称空间下的所有的</span>Web<span>控件在</span>ASPX<span>的</span>HTML<span>源代码中的标签前缀，这里为&#8220;</span>SkyWebControl<span>&#8221;。</span></p>
<p><span>这个文件中定义了</span>3<span>个类型。</span></p>
<p><strong>SkyTreeViewControlBuilder</strong></p>
<p><span>这个类型是从</span>System.Web.UI.ControlBuilder<span>上派生的。本类型用于对</span>VS.NET<span>的</span>WEB<span>窗体设计器提供支持。</span></p>
<p><strong>SkyTreeViewControlDesigner</strong></p>
<p><span>这个类型是从</span>System.Web.UI.Design.ControlDesigner <span>上派生的，用于对</span>VS.NET<span>的</span>WEB<span>窗体设计器提供支持。</span></p>
<p><strong>SkyTreeViewControl</strong></p>
<p><span>这个类型就是树状列表</span>WEB<span>控件了。首先看到它的定义头。</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000">[System.Web.UI.ControlBuilder(&nbsp;</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(&nbsp;SkyTreeViewControlBuilder&nbsp;))]<br />[System.ComponentModel.Designer(&nbsp;</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(&nbsp;SkyTreeViewControlDesigner&nbsp;))]<br />[System.Drawing.ToolboxBitmap(&nbsp;</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(&nbsp;SkyTreeViewControl&nbsp;))]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;SkyTreeViewControl&nbsp;:&nbsp;System.Web.UI.WebControls.WebControl</span></div>
<p>这个类型是从</span>System.Web.UI.WebControls.WebControl<span>上派生的。它还附加了</span>3<span>个特性，其中</span>ControlBuilder<span>特性用于指明控件配套的控件创建者类型为</span>SkyTreeViewControlBuilder<span>，</span>Designer<span>特性用于指明控件配套的设计器类型为</span>SkyTreeViewControlDesigner<span>，而特性</span>ToolboxBitmap<span>用于指明控件类型在</span>VS.NET<span>的窗体设计器的工具箱中使用什么样的图标。这里指明使用图标&#8220;</span><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage013.jpg" width="16" height="16" /><span>&#8221;。</span></p>
<p><span>本控件定义了</span>Nodes<span>属性，其代码为</span></p>
<p>&nbsp;</p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;SkyTreeNodeList&nbsp;myNodes&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SkyTreeNodeList();<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;子节点列表<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">[System.ComponentModel.Browsable(&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">&nbsp;)]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SkyTreeNodeList&nbsp;Nodes<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;myNodes&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myNodes&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p>Nodes<span>属性保存了树状列表控件的根节点。该属性使用代码&#8220;</span>[System.ComponentModel.<span style="color: #154857">Browsable( <span style="color: blue">false</span> )]</span><span>&#8221;声明该属性在设计器中的属性列表中是看不见的。本控件还定义了</span>AllNodes<span>属性用于获得树状列表所包含的所有节点组成的列表。</span></p>
<p><span>本控件定义了</span>IndentXML<span>属性，其定义代码为</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;bolIndentXML&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;XML是否进行缩进<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;remarks&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;若控件的IndentXML属性值为True，则控件内部生成的XML文本将带缩进，便于开发人员调试<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;程序，但这将增加页面大小，因此当程序调试完毕后可以设置IndentXML属性值为false来<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;减小页面大小，提高性能。<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/remarks&gt;</span><span style="color: #808080"><br /></span><span style="color: #000000">[System.ComponentModel.DefaultValue(&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">&nbsp;)]<br />[System.ComponentModel.Description(</span><span style="color: #800000">"</span><span style="color: #800000">生成XML是否进行缩进</span><span style="color: #800000">"</span><span style="color: #000000">)]<br />[System.ComponentModel.Category(</span><span style="color: #800000">"</span><span style="color: #800000">Behavior</span><span style="color: #800000">"</span><span style="color: #000000">)]<br /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;IndentXML<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">get</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;bolIndentXML&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">set</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bolIndentXML&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p>该属性用于表示生成的</span>XML<span>源代码是否进行缩进。若</span>XML<span>源代码进行缩进，则方便开发人员直接查看</span>XML<span>源代码，但这样会增加页面大小，因此当应用程序处于开发时可以设置树状列表的控件的</span>IndentXML<span>属性值为</span>true<span>，当开发完成部署时可设置该属性值为</span>false<span>。</span></p>
<p><span>此外控件还定义了以下几个属性</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 131.4pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="175">
<p>AutoScroll</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 392.4pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="523">
<p><span>获得或设置控件是否自动显示横向和纵向滚动条，若该属性值为</span>false<span>，则无论控件显示多少内容，控件都不会显示滚动条。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 131.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="175">
<p>GenerateAtServer</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 392.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="523">
<p><span>获得或设置控件是否在服务器端生成显示树状列表的</span>HTML<span>代码，若该属性值为</span>true<span>，则控件会在</span>ASP.NET<span>服务器端生成显示树状列表的</span>HTML<span>代码，这会加大服务器的工作量，并导致页面比较大；若该属性值为</span>false<span>，则控件会在客户端浏览器中使用</span>JavaScript/XSLT<span>来生成</span>HTML<span>代码，此时会减少服务器工作量，并减少输出的页面的大小。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 131.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="175">
<p>DynamicLoadChildNodes</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 392.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="523">
<p><span>获取或设置控件是否动态加载子节点列表，若该属性值为</span>True<span>，则控件允许动态加载节点的子节点，此时控件不会刷新页面，而加载树状节点对象的</span>XMLSource<span>属性指定的</span>XML<span>文档来动态的生成子节点；若该属性值为</span>False<span>则禁止这种功能。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 131.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="175">
<p>TagKey</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 392.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="523">
<p><span>控件重载了</span>TagKey<span>属性，设置该控件最外层使用&#8220;</span>DIV<span>&#8221;标签。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 131.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="175">
<p>TreeNodeStyleString</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 392.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="523">
<p><span>树状列表节点使用的</span>CSS<span>样式字符串。</span></p></td></tr>
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 131.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="175">
<p>SelectedNodeStyleString</p></td>
<td style="border-bottom: windowtext 1pt solid; border-left: medium none; padding-bottom: 0cm; padding-left: 5.4pt; width: 392.4pt; padding-right: 5.4pt; border-top: medium none; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="523">
<p><span>处于选中状态的树状节点使用的</span>CSS<span>样式字符串。</span></p></td></tr></table>
<p><strong>&nbsp;</strong></p>
<p><strong>OnLoad </strong><strong><span>函数</span></strong></p>
<p><span>控件重写了</span>WebControl<span>的</span>OnLoad<span>函数，其代码为</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;控件加载时的处理，此时控件尚未向页面输出HTML代码。<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="e"&gt;</span><span style="color: #008000">事件参数</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;OnLoad(EventArgs&nbsp;e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.OnLoad&nbsp;(e);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;包含树状列表节点样式的HTML代码</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strStyleHtml&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">\r\n.SkyTreeViewControl_TreeNode&nbsp;{&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.TreeNodeStyleString&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">}</span><span style="color: #800000">"</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">\r\n.SkyTreeViewControl_SelectedNode{</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.SelectedNodeStyleString&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">}\r\n</span><span style="color: #800000">"</span><span style="color: #000000">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;添加树状节点使用的CSS样式代码</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">this</span><span style="color: #000000">.Page.Header&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若在ASPX的HTML代码中使用了&#8220;&lt;head&nbsp;runat=server&gt;<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />.&lt;/head&gt;&#8221;则<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;this.Page.Header属性有效，可以向head标签下添加新内容。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;按照比较严格的HTML规范，style标签只能放置在head标签下面。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;ASP.NET2.0支持this.Page.Header属性,但ASP.NET1.0/1.1不支持。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;find&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">foreach</span><span style="color: #000000">&nbsp;(System.Web.UI.Control&nbsp;ctl&nbsp;</span><span style="color: #0000ff">in</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Page.Header.Controls)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;搜索Header下面的所有的子元素，看看是否已经输出过树状列表<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;节点样式元素。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(ctl.ID&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyTreeViewControl_Style</span><span style="color: #800000">"</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;find&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(find&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若以前没有输出则向Header元素下添加新的style元素，并设置其内容。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HtmlGenericControl&nbsp;style&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;HtmlGenericControl(</span><span style="color: #800000">"</span><span style="color: #800000">style</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style.ID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyTreeViewControl_Style</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style.InnerHtml&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;strStyleHtml;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Page.Header.Controls.Add(style);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;不能在Render或RenderContents函数中使用RegisterClientScriptBlock<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;因为那时RegisterClientScriptBlock函数的功能已经不在状态，无效了。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;而OnLoad函数中页面尚未开始输出，此时RegisterClientScriptBlock函数<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;是有效的。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Page.ClientScript.RegisterClientScriptBlock(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType(),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyTreeViewControl_Style</span><span style="color: #800000">"</span><span style="color: #000000">,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&lt;style&gt;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;strStyleHtml&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&lt;/style&gt;</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p>这里的树状节点列表需要根据其选择状态而使用属性&#8220;</span>TreeNodeStyleString<span>&#8221;或&#8220;</span>SelectedNodeStyleString<span>&#8221;中指定的</span>CSS<span>样式，为了减少</span>HTML<span>代码量，将生成一个</span>style<span>的</span>HTML<span>标签，该标签包含了属性&#8220;</span>TreeNodeStyleString<span>&#8221;或&#8220;</span>SelectedNodeStyleString<span>&#8221;指定的</span>CSS<span>样式，而对树状列表节点采用&#8220;</span>class=&#8217;<span>样式名称</span>&#8217;<span>&#8221;来选择其</span>CSS<span>显示样式。</span></p>
<p><span>按照比较严格的</span>HTML<span>语法，</span>style<span>标签必须放置在</span>HTML<span>文档中的</span>head<span>标签里面，因此本控件尽量将</span>style<span>标签放置在</span>head<span>标签中。</span></p>
<p><span>在</span>ASP.NET2.0<span>中，</span>WEB<span>控件可以使用属性&#8220;</span>this.Page.Header<span>&#8221;获得</span>ASPX<span>中的</span>head<span>标签，若</span>ASPX<span>的</span>HTML<span>代码中使用了&#8220;</span>&lt;head runat=server&gt;&#8230;.&lt;/head&gt;<span>&#8221;，则属性&#8220;</span>this.Page.Header<span>&#8221;属性是有效的，若</span>head<span>标签没有标记为&#8220;</span>runat=server<span>&#8221;则&#8220;</span>this.Page.Header<span>&#8221;属性值是空引用，由于笔者无法强制开发人员使用&#8220;</span>&lt;head runat=server&gt;<span>&#8221;标记，因此在此需要进行判断&#8220;</span>this.Page.Header<span>&#8221;属性值是否为空。注意</span>ASP.NET1.0/1.1<span>不支持&#8220;</span>this.Page.Header<span>&#8221;属性。</span></p>
<p><span>若&#8220;</span>this.Page.Header<span>&#8221;属性有效，则还需要遍历页面</span>head<span>标签下面的所有的子元素，若没有找到</span>ID<span>号为&#8220;</span>SkyTreeViewControl_Style<span>&#8221;则元素则向其添加一个</span>ID<span>号为&#8220;</span>SkyTreeViewControl_Style<span>&#8221;的标签为&#8220;</span>style<span>&#8221;的</span>HTML<span>元素，此举是为了放置当同一个页面上有多个树状列表控件时重复的向&#8220;</span>head<span>&#8221;标签输出&#8220;</span>style<span>&#8221;标签。</span></p>
<p><span>若&#8220;</span>this.Page.Header<span>&#8221;属性为空，则只能使用非标准的</span>HTML<span>语法来输出</span>style<span>标签了。这里使用了函数&#8220;</span>this.Page.ClientScript.RegisterClientScriptBlock<span>&#8221;，这</span><span>个函数用于向页面特定的部分输出</span>HTML<span>代码。</span></p>
<p><span>在</span>ASP.NET<span>中，任何标记为&#8220;</span>runat=server<span>&#8221;的</span>WEB<span>控件必须包含在标记为&#8220;</span>runat=server<span>&#8221;的</span>FORM<span>元素中。当页面程序或</span>WEB<span>控件内部调用</span>RegisterClientScriptBlock <span>函数时，</span>ASP.NET<span>框架会紧跟着</span>Form<span>元素的起始标记</span>(<span>也就是</span>HTML<span>代码&#8220;</span>&lt;form runat=server &#8230; &gt;<span>&#8221;</span>)<span>后插入指定的</span>HTML<span>代码。这个函数有三个参数，第一个参数为</span>WEB<span>控件的类型，第二个是用于标记</span>HTML<span>代码块的名称，第三个是</span>HTML<span>代码字符串。若在同一种（注意，不是同一个）</span>WEB<span>控件中调用了多次</span>RegisterClientScriptBlock<span>函数，但使用了相同的</span>HTML<span>代码块名称，则仍然只输出一次。这样能避免一个页面上同一个类型的多个</span>WEB<span>控件多次输出相同的</span>HTML<span>代码。</span></p>
<p><span>类似的，</span>ASP.NET<span>还提供一个</span>RegisterStartupScript <span>函数，函数参数也是</span>HTML<span>代码块的名称和</span>HTML<span>代码字符串。但它会紧挨着</span>Form<span>元素的结束标签</span>(<span>也就是</span>HTML<span>代码&#8220;</span>&lt;/form&gt;<span>&#8221;</span>)<span>的前面插入指定的</span>HTML<span>代码。下面的代码说明了函数</span>RegisterClientScriptBlock<span>和</span>RegisterStartupScript<span>的输出区域。</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 523.8pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="698">
<p>&lt;form runat=server method=post&gt;</p>
<p>[RegisterClientScriptBlock<span>函数输出区域</span>]</p>
<p>&nbsp;</p>
<p><span>定义内容的</span>HTML<span>代码，定义</span>WEB<span>控件的</span>HTML<span>代码</span></p>
<p>&nbsp;</p>
<p>[RegisterStartupScript<span>函数输出区域</span>]</p>
<p>&lt;/form&gt;</p></td></tr></table>
<p>&nbsp;</p>
<p><strong>Render </strong><strong><span>函数</span></strong></p>
<p style="text-align: left; text-indent: 21pt" align="left">WEB<span>控件使用</span>Render<span>函数向页面输出</span>HTML<span>代码。其代码为</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;输出控件HTML内容<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="writer"&gt;</span><span style="color: #008000">HTML书写器</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Render(System.Web.UI.HtmlTextWriter&nbsp;writer)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.AutoScroll&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Style[</span><span style="color: #800000">"</span><span style="color: #800000">overflow</span><span style="color: #800000">"</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">auto</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.Render(&nbsp;writer&nbsp;);<br />}</span></div>
<p style="text-align: left; text-indent: 21pt" align="left">在这里会进行判断，若控件设置了</span>AutoScroll<span>属性，也就是当树状列表要显示的节点比较多时，控件自动显示滚动条，这里就设置控件的&#8220;</span>overflow<span>&#8221;样式值为&#8220;</span>auto<span>&#8221;。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p style="text-align: left; text-indent: 21pt" align="left">ASP.NET<span>框架处理原始的</span>ASPX<span>文件时，遇到</span>WEB<span>控件标签时会去掉这个标签，然后转而调用</span>WEB<span>控件的</span>Render<span>函数。比如在</span>Default.ASPX<span>中有一段</span>HTML</p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 523.8pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="698">
<p align="left"><span style="font-family: 新宋体; color: blue; font-size: 10pt">&lt;</span><span style="font-family: 新宋体; color: #a31515; font-size: 10pt">SkyWebControl</span><span style="font-family: 新宋体; color: blue; font-size: 10pt">:</span><span style="font-family: 新宋体; color: #a31515; font-size: 10pt">SkyTreeViewControl</span><span style="font-family: 新宋体; font-size: 10pt"> <span style="color: red">id</span><span style="color: blue">="myTreeView"</span> <span style="color: red">runat</span><span style="color: blue">="server" </span></span><span style="font-family: 新宋体; color: blue; font-size: 10pt">其他属性</span><span style="color: blue; font-size: 10pt">&#8230;&#8230;</span><span style="font-family: 新宋体; color: blue; font-size: 10pt"> &gt;<br />&lt;/</span><span style="font-family: 新宋体; color: #a31515; font-size: 10pt">SkyWebControl</span><span style="font-family: 新宋体; color: blue; font-size: 10pt">:</span><span style="font-family: 新宋体; color: #a31515; font-size: 10pt">SkyTreeViewControl</span><span style="font-family: 新宋体; color: blue; font-size: 10pt">&gt;</span></p></td></tr></table>
<p style="text-align: left; text-indent: 21pt" align="left"><span>当</span>ASP.NET<span>框架处理这个</span>HTML<span>代码片段时，会将&#8220;</span>SkyWebControl:SkyTreeViewControl<span>&#8221;标签整个的删除掉，然后转而调用</span>WEB<span>控件的</span>Render<span>函数，将这个函数输出的</span>HTML<span>代码替换掉</span>ASPX<span>中的</span>WEB<span>控件标签。此时</span>ASPX<span>中的</span>WEB<span>控件标签成了</span>WEB<span>控件在</span>HTML<span>文档中的占位符。这就是所有</span>WEB<span>控件输出</span>HTML<span>代码的原理，不会有例外。</span></p>
<h3>RenderContents <span>函数</span></h3>
<p style="text-align: left; text-indent: 21pt" align="left"><span>控件的</span>Rander<span>函数调用了&#8220;</span>base.Rander<span>&#8221;函数，而&#8220;</span>base.Rander<span>&#8221;函数内部会调用</span>RenderContents<span>函数来输出控件的内容。因此这里控件重写了</span>RenderContents<span>函数用来输出详细内容。这个函数是树状列表控件</span>C#<span>代码的主要内容。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>本函数的第一个部分就是判断控件是否处于设计模式，也就是判断控件是否运行在</span>VS.NET<span>的</span>Web<span>窗体设计器中，其代码如下</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.Page.Site&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.Page.Site.DesignMode&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若ASPX页面是处于设计状态，比如处于VS.NET集成开发环境的WEB表单设计器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;中，则本WEB控件不显示实际内容，只是显示控件的一些状态。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;b&gt;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&lt;/b&gt;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;Type=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;t.FullName&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;Version=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;t.Assembly.FullName&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;GenerateAtServer=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GenerateAtServer&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;DynamicLoadChildNodes=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.DynamicLoadChildNodes&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;AutoScroll=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.AutoScroll&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;IndentXML=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.IndentXML&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteLine(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;br&nbsp;/&gt;Yfyuan&nbsp;release&nbsp;at&nbsp;2008-2-19</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</span></div>
<p style="text-align: left; text-indent: 21pt" align="left">在这里判断</span> base.Page.Site.DesignMode <span>属性。若该属性值为</span> true , <span>则表明控件处于设计模式，出现在</span>VS.NET<span>的窗体设计器中。此时控件就是简单地输出控件的名称类型和一些重要属性值。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left">&nbsp;</p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>若控件不处于设计器中，那就是真正的运行了。若允许客户端动态加载子节点，则输出支持动态加载子节点的</span>HTML<span>代码块，这里使用了</span>RegisterStartupScript<span>函数。将在客户端的</span>form<span>标签结束前输出这些</span>HTML<span>代码。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>这里要注意一下，在</span>Render<span>和</span>RenderContents<span>函数中调用</span>RegisterClientScriptBlock<span>函数是无意义的，因为早在任何</span>WEB<span>控件输出前，</span>form<span>标签已经开始并输出了一些内容了，已经输出的内容是不可更改的，因此</span>Render<span>或</span>RenderContents<span>中不能调用</span>RegisterClientScriptBlock<span>函数，而应当在控件的的</span>OnLoad<span>方法或</span>Load<span>事件处理中调用</span>RegisterClientScriptBlock<span>函数。</span></p>
<h4><span>第一段</span>HTML<span>代码块</span></h4>
<p style="text-align: left; text-indent: 21pt" align="left"><span>若控件的&#8220;</span>DynamicLoadChildNodes<span>&#8221;属性值为</span>true<span>，也就是控件运行在客户端动态加载子节点，则输出支持客户端动态加载子节点的</span>HTML<span>代码，首先输出一个名为&#8220;</span>SkyTreeViewControlTempXML<span>&#8221;的</span>XML<span>数据岛标签，并将它的&#8220;</span>onreadystatechange<span>&#8220;事件绑定到&#8221;</span>SkyTreeViewControlDynamicLoadChildNodes<span>&#8221;的</span>JavaScript<span>函数上。这里还定义了一个名称为&#8220;</span>SkyTreeViewControlDyanmicRootNodeID<span>&#8221;的全局变量，用于指明是哪个节点正在加载在节点。这里输出的</span>HTML<span>代码内容为</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;定义一个XML数据岛标签<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;当动态加载子节点时使用该XML数据岛来加载定义子节点的XML文档，<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;XML数据岛是IE特有技术，其他浏览器可能不支持。<br /><br /></span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xml&nbsp;</span><span style="color: #ff0000">id</span><span style="color: #0000ff">='SkyTreeViewControlTempXML'<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">onreadystatechange</span><span style="color: #0000ff">='SkyTreeViewControlDynamicLoadChildNodes()'&nbsp;</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">xml</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">script&nbsp;</span><span style="color: #ff0000">language</span><span style="color: #0000ff">=javascript</span><span style="color: #0000ff">&gt;</span><span style="background-color: #f5f5f5; color: #000000"><br /><br /></span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">---------&nbsp;开始定义动态加载子节点使用的JavaScript&nbsp;代码---------------------</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000"><br /></span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;当前动态加载子节点的根节点对象编号</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;;<br /><br /></span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;动态加载子节点</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #0000ff">function</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;SkyTreeViewControlDynamicLoadChildNodes()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得加载子节点定义数据的XML数据岛对象</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;xml&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">SkyTreeViewControlTempXML</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;xml&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">==</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">return</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;xml.readyState&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">complete</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;此时说明XML数据岛正处于工作状态，取消当前操作</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">return</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得当前正在处理的树状列表节点对象</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;RootNode&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">_text</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;RootNode&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">==</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">return</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;html&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">''</span><span style="background-color: #f5f5f5; color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;errorflag&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">false</span><span style="background-color: #f5f5f5; color: #000000">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得包含XSLT代码的XML数据岛对象</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;xsl&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">SkyTreeViewControlXSLT</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;xsl&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">==</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;未找到XSLT文档则设置错误信息</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;html&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">缺失XSLT数据</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorflag&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">true</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">else</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;xml.XMLDocument.parseError.errorCode&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">0</span><span style="background-color: #f5f5f5; color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;若加载定义子节点的XML文档错误则设置错误信息</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;html&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">错误:</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;xml.XMLDocument.parseError.reason<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">[</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;xml.XMLDocument.parseError.url&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">]</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorflag&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">true</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">else</span><span style="background-color: #f5f5f5; color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;xml.XMLDocument.documentElement&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">==</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;html&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">未找到根节点</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorflag&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">true</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">else</span><span style="background-color: #f5f5f5; color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;将当前节点的HTML标签的编号保存到XML文档中。</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xml.XMLDocument.documentElement.setAttribute(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">RootID</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;执行XSLT转换，生成用于显示子列表的HTML字符串</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;html&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;xml.XMLDocument.transformNode(&nbsp;xsl.XMLDocument&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;将当前节点的&#8220;正在加载<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&#8221;的字样删掉</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;lbl&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">_Loading</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;lbl&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;errorflag&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbl.innerHTML&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&lt;br&nbsp;/&gt;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;html&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">return</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;将动态生成的HTML代码输出到HTML页面中</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbl.insertAdjacentHTML(</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">afterEnd</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">,&nbsp;html&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbl.parentNode.removeChild(&nbsp;lbl&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">else</span><span style="background-color: #f5f5f5; color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;将动态生成的HTML代码输出到HTML页面中</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RootNode.insertAdjacentHTML(</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">afterEnd</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">,&nbsp;html&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得节点的展开点图片对象</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myExpend&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">_expend</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得节点的图标图片对象</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">_icon</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得节点的文本对象</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">_text</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;获得子节点表格&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myTable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">+</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">_table</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">if</span><span style="background-color: #f5f5f5; color: #000000">(&nbsp;myExpend&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">&amp;&amp;</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myIcon&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">&amp;&amp;</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myText&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">&amp;&amp;</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myTable&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">!=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">&nbsp;将当前节点的控制图标从收缩状态改变为展开状态</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">var</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;SrcBack&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myIcon.src&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myIcon.src&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myIcon.getAttribute(</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">SrcBack</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myIcon.setAttribute(&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">SrcBack</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;,&nbsp;SrcBack&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SrcBack&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myExpend.src&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myExpend.src&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;myExpend.getAttribute(</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">SrcBack</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myExpend.setAttribute(&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">SrcBack</span><span style="background-color: #f5f5f5; color: #000000">'</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;,&nbsp;SrcBack&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">myTable.scrollIntoView(&nbsp;false&nbsp;);</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="background-color: #f5f5f5; color: #000000">=</span><span style="background-color: #f5f5f5; color: #000000">&nbsp;</span><span style="background-color: #f5f5f5; color: #0000ff">null</span><span style="background-color: #f5f5f5; color: #000000">;<br /><br />}</span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">function&nbsp;SkyTreeViewControlDynamicLoadChildNodes()</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000"><br /></span><span style="background-color: #f5f5f5; color: #008000">//</span><span style="background-color: #f5f5f5; color: #008000">--------&nbsp;本段JavaScript&nbsp;定义结束--------------------------</span><span style="background-color: #f5f5f5; color: #008000"><br /></span><span style="background-color: #f5f5f5; color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">script</span><span style="color: #0000ff">&gt;</span></div>
<p style="text-align: left; text-indent: 21pt" align="left">当用户展开一个节点而导致动态加载子节点时，其他的</span>JavaSciprt<span>代码会设置节点的</span>XMLSource<span>属性值到这个名为&#8220;</span>SkyTreeViewControlTempXML<span>&#8221;的</span>XML<span>数据岛的</span>src<span>属性上。这会导致</span>IE<span>浏览器立即开始异步的加载</span>XML<span>文档，并根据其文档加载状态而多次触发&#8220;</span>onreadystatechange<span>&#8221;事件，从而调用</span>JavaScript<span>函数&#8220;</span>SkyTreeViewControlDynamicLoadChildNodes<span>&#8221;，在这个</span>JavaScript<span>函数中，首先获得</span>XML<span>数据岛对象，然后判断其状态，若状态值不等于&#8220;</span>complete<span>&#8221;时，则文档还没有完成加载，从而退出等待下一次调用。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>若</span>XML<span>数据岛完成加载后，获得父节点的文本元素，然后获得嵌入在</span>HTML<span>文档中另外一个名为&#8220;</span>SkyTreeViewControlXSLT<span>&#8221;的</span>XML<span>数据岛，这个</span>XML<span>数据岛包含了</span>XSLT<span>文档。然后使用刚刚加载的</span>XML<span>文档，调用它的&#8220;</span>transfromNode<span>&#8221;函数执行</span>XSLT<span>转换，则转换结果就是显示子节点的</span>HTML<span>字符串。然后使用</span>HTML<span>元素的&#8220;</span>insertAdjacentHTML<span>&#8221;函数将生成的</span>HTML<span>字符串输出到</span>HTML<span>页面上。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>成功的动态加载子节点后，</span>JavaScript<span>脚本还更新父节点的图标，使其表示为展开状态。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<h4><span>第二段</span>HTML<span>代码块</span></h4>
<p style="text-align: left; text-indent: 21pt" align="left">WEB<span>控件输出完第一段</span>HTML<span>代码后，会根据需要输出第二段代码，第二段代码包含在客户端执行</span>XSLT<span>转换所需的</span>XSLT<span>模板代码以及初始化生成树状列表的</span>HTML<span>代码的</span>JavaScript<span>代码，其</span>C#<span>代码为</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GenerateAtServer&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.DynamicLoadChildNodes&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若允许动态加载子节点而且不是在服务器段生成HTML代码<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;则输出动态加载子节点使用的JavaScript代码</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">!</span><span style="color: #0000ff">base</span><span style="color: #000000">.Page.ClientScript.IsStartupScriptRegistered(&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType()&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyTreeViewControlXSLT</span><span style="color: #800000">"</span><span style="color: #000000">))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;输出第二段HTML代码块</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.Page.ClientScript.RegisterStartupScript(&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType()&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyTreeViewControlXSLT</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000"><br />&lt;!--&nbsp;使用一个XML数据岛保存客户端动态生成HTML代码时使用的XSLT代码--&gt;<br />&lt;xml&nbsp;id='SkyTreeViewControlXSLT'&gt;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;ReadXSLTString()&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;此处从资源文件SkyTreeViewControl.xslt中获得XSLT代码</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000">&lt;/xml&gt;<br /><br />&lt;script&nbsp;language=javascript&gt;<br /><br />//---------------&nbsp;生成树状列表--------------------------------------<br />//&nbsp;参数id&nbsp;就是树状列表控件的编号<br />function&nbsp;RefreshSkyTreeViewControl(&nbsp;id&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;xml&nbsp;=&nbsp;document.getElementById(&nbsp;id&nbsp;+&nbsp;'_xml');<br />&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;xsl&nbsp;=&nbsp;document.getElementById(&nbsp;'SkyTreeViewControlXSLT');<br />&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;container&nbsp;=&nbsp;document.getElementById(&nbsp;id&nbsp;+&nbsp;'_container'&nbsp;&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;container&nbsp;==&nbsp;null&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert('未找到目标');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;container&nbsp;!=&nbsp;null&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;xml&nbsp;==&nbsp;null&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.innerText&nbsp;=&nbsp;'缺失XML数据';<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;xsl&nbsp;==&nbsp;null&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.innerText&nbsp;=&nbsp;'缺失XSLT数据';<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;html&nbsp;=&nbsp;xml.XMLDocument.transformNode(&nbsp;xsl.XMLDocument&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;container.innerHTML&nbsp;=&nbsp;html&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}//function&nbsp;RefreshSkyTreeViewControl(&nbsp;id&nbsp;)<br /><br />&lt;/script&gt;</span><span style="color: #800000">"</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /></span></div>
<p style="text-align: left; text-indent: 21pt" align="left">在这里程序会判断控件的</span>GenerateAtServer<span>和</span>DynamicLoadChildNodes <span>的属性值，若</span>WEB<span>控件不是在服务器端生成</span>HTML<span>代码或者允许在客户端动态加载子列表就会输出第二段</span>HTML<span>代码。</span></p>
<p style="text-align: left; text-indent: 21pt" align="left"><span>在输出第二段</span>HTML<span>代码时，首先会输出一个名为&#8220;</span>SkyTreeViewControlXSLT<span>&#8221;的</span>XML<span>数据岛元素，该数据岛内容来自函数&#8220;</span>ReadXSLTString<span>&#8221;，该函数就是简单的从一个名为&#8220;</span>SkyTreeViewControl.xslt<span>&#8221;的嵌入式程序集资源中读取所有的文本内容。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>此处还输出一个为&#8220;</span>RefreshSkyTreeViewControl<span>&#8221;的</span>JavaScript<span>函数，用于初始化一个树状列表，其参数就是树状列表的编号。也就是&#8220;</span>myTreeView<span>&#8221;，&#8220;</span>myTreeView2<span>&#8221;之类的控件客户端编号。在</span>JavaScript<span>函数中，首先获得第三个</span>XML<span>数据岛，获得树状节点定义信息</span>XML<span>文档，然后和&#8220;</span>SkyTreeViewControlXSLT<span>&#8221;数据岛中的</span>XSLT<span>文档执行</span>XSLT<span>转换，生成</span>HTML<span>字符串，然后调用</span>HTML<span>元素的&#8220;</span>innerHTML<span>&#8221;属性向</span>HTML<span>文档填充刚刚生成的</span>HTML<span>代码，从而展现出一个树状结构。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>本过程配套使用的&#8220;</span>ReadXSLTString<span>&#8221;函数的代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;strXSLString&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;从程序集资源文件SkyTreeViewControl.xslt中加载XSLT代码。<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;returns&gt;</span><span style="color: #008000">加载的XSLT代码字符串</span><span style="color: #808080">&lt;/returns&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;ReadXSLTString()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(strXSLString&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">foreach</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;name&nbsp;</span><span style="color: #0000ff">in</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType().Assembly.GetManifestResourceNames())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;查询程序集中所有的嵌入的资源的名称，找到以"SkyTreeViewControl.xslt"<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;结尾的程序集资源并以UTF8的文本编码格式加载其中的文本内容。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;程序集资源的全名为&#8220;程序集默认名称空间.保存文件的各级目录.文件名&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;其中文件名中不能出现下划线。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(name.EndsWith(</span><span style="color: #800000">"</span><span style="color: #800000">.SkyTreeViewControl.xslt</span><span style="color: #800000">"</span><span style="color: #000000">))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;(System.IO.Stream&nbsp;stream&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType().Assembly.GetManifestResourceStream(name))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.IO.StreamReader&nbsp;reader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.IO.StreamReader(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Text.Encoding.UTF8);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strXSLString&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;reader.ReadToEnd();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strXSLString;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Exception(</span><span style="color: #800000">"</span><span style="color: #800000">未找到程序集资源SkyTreeViewControl.xslt</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;strXSLString;<br />}</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">本函数中，程序会遍历程序集中所有的嵌入式的资源名称，若该名称以&#8220;</span>.SkyTreeViewControl.xslt<span>&#8221;结尾则以</span>UTF8<span>的编码格式读取该资源的文本内容。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left">&nbsp;</p>
<h4><span>第三段</span>HTML<span>代码块</span></h4>
<p style="text-align: left; text-indent: 21.3pt" align="left">WEB<span>控件还会输出一个名为&#8220;</span>SkyTreeViewControlExpendNodebyID<span>&#8221;的</span>JavaScript<span>函数，该函数用于展开或收缩节点，而与之配套的定义了一个名为</span>SkyTreeViewControlCurrentTreeNode<span>的全局变量，用于保存当前高亮度显示的节点的编号。这段</span>JavaScript<span>代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;定义树状列表的当前节点对象</span><span style="color: #008000"><br /></span><span style="color: #000000">var&nbsp;SkyTreeViewContrlCurrentTreeNode&nbsp;;<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000"><br /></span><span style="color: #008000">//</span><span style="color: #008000">----------------&nbsp;展开指定编号的树状列表的节点---------------<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;参数strID&nbsp;指明节点的ID号<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;参数bolSelect&nbsp;指明是否高亮度显示这个树状列表节点<br /></span><span style="color: #008000">//<br /></span><span style="color: #000000">function&nbsp;SkyTreeViewContrlExpendNodeByID(strID&nbsp;,&nbsp;bolSelect&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获得节点的展开点图片对象</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;myExpend&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;document.getElementById(strID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">_expend</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获得节点的图标图片对象</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;myIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;document.getElementById(strID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">_icon</span><span style="color: #800000">'</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获得节点的文本对象</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;myText&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;document.getElementById(strID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">_text</span><span style="color: #800000">'</span><span style="color: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获得子节点表格</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;myTable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;document.getElementById(strID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">_table</span><span style="color: #800000">'</span><span style="color: #000000">);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;myText&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;bolSelect&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置树状列表节点高亮度显示</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;SkyTreeViewContrlCurrentTreeNode&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;myText<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;SkyTreeViewContrlCurrentTreeNode&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeViewContrlCurrentTreeNode.className&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">SkyTreeViewControl_TreeNode</span><span style="color: #800000">'</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeViewContrlCurrentTreeNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myText;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeViewContrlCurrentTreeNode.className&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">SkyTreeViewControl_SelectedNode</span><span style="color: #800000">'</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;展开或收缩子节点</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;myExpend&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;myIcon&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;myTable&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;切换节点前面的展开或收缩样式的图标</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;SrcBack&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myIcon.src&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myIcon.src&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myIcon.getAttribute(</span><span style="color: #800000">'</span><span style="color: #800000">SrcBack</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myIcon.setAttribute(&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">SrcBack</span><span style="color: #800000">'</span><span style="color: #000000">&nbsp;,&nbsp;SrcBack&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;切换节点前面的+&nbsp;或者-&nbsp;样式的图标</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SrcBack&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myExpend.src&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myExpend.src&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myExpend.getAttribute(</span><span style="color: #800000">'</span><span style="color: #800000">SrcBack</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myExpend.setAttribute(&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">SrcBack</span><span style="color: #800000">'</span><span style="color: #000000">&nbsp;,&nbsp;SrcBack&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;显示或隐藏包含子节点的表格对象</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;myTable.style.display&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">none</span><span style="color: #800000">'</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myTable.style.display</span><span style="color: #000000">=</span><span style="color: #800000">'</span><span style="color: #800000">none</span><span style="color: #800000">'</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myTable.style.display</span><span style="color: #000000">=</span><span style="color: #800000">''</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;dyload&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;myTable&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若不存在包含子节点的表格对象则尝试动态加载子节点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;此时节点的XMLSource扩展属性就保存着定义子节点的XML文档URL地址。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;XMLSource&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myText.getAttribute(</span><span style="color: #800000">'</span><span style="color: #800000">XMLSource</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;XMLSource&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;XMLSource.length&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若设置了该XML文档地址则删除XMLSource&nbsp;扩展属性并</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myText.removeAttribute(</span><span style="color: #800000">'</span><span style="color: #800000">XMLSource</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;xml&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;document.getElementById(&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">SkyTreeViewControlTempXML</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;xml&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置&#8220;正在加载<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&#8221;字样为显示状态</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;strID&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;lbl&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;document.getElementById(&nbsp;SkyTreeViewControlDyanmicRootNodeID&nbsp;</span><span style="color: #000000">+</span><span style="color: #800000">'</span><span style="color: #800000">_Loading</span><span style="color: #800000">'</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;lbl&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lbl.style.display&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">''</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;调用编号为SkyTreeViewControlTempXML&nbsp;的XML数据岛来异步加载XML文档</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xml.src&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;XMLSource&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dyload&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">true</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;dyload&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">myText.scrollIntoView(&nbsp;false&nbsp;);</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />}</span><span style="color: #008000">//</span><span style="color: #008000">function&nbsp;SkyTreeViewContrlExpendNodeByID(strID)</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">这个</span>JavaScript<span>函数有两个参数，第一个参数是节点编号，第二个参数是是否设置该节点为当前节点，也就是是否设置高亮度显示（一般的就是蓝底白字）。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>在这个</span>JavaScript<span>函数里面，首先根据节点编号获得节点的图标，文本和包含子节点列表的表格对象。并根据需要设置当前高亮度显示的节点对象。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>若子节点列表存在则需要展开和收缩子节点列表，此时将节点图标的</span>src<span>属性和它们的扩展属性</span>SrcBack<span>值进行互换，从而切换了图标，还对包含子节点列表的表格对象在可见状态和不可见状态间进行切换。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>若子节点列表不存在而且节点的</span>XMLSource<span>属性有效则开始动态加载子节点。首先获得名为&#8220;</span>SkyTreeViewControlTempXML<span>&#8221;的</span>XML<span>数据岛对象，本控件输出的第一段</span>HTML<span>代码中已经包含了该</span>XML<span>数据岛。设置</span>JavaScript<span>全局变量&#8220;</span>SkyTreeViewControlDyanmicRootNodeID<span>&#8221;的值为当前节点的编号，然后设置这个</span>XML<span>数据岛的</span>src<span>属性值为节点的</span>XMLSource<span>属性值。之后</span>IE<span>浏览器就异步的加载</span>XML<span>文档，转而执行第一段</span>HTML<span>代码块中的</span>JavaScript<span>脚本了。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left">&nbsp;</p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>上面的代码都是使用</span>RegisterStartupScript<span>函数输出了三段</span>HTML<span>代码块。接下来就是输出控件的</span>HTML<span>代码内容了。</span></p>
<h4><span>输出控件</span>HTML<span>代码</span></h4>
<p style="text-align: left; text-indent: 21.3pt" align="left">C#<span>代码首先在内存中创建一个</span>XML<span>文档书写器，创建一个</span>System.Xml.Serialization.XmlSerializer<span>类型的对象，使用</span>XML<span>序列化技术将控件</span>Nodes<span>属性中的树状节点保存到一个</span>XML<span>文档中，实现这个功能的代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;在内存中创建一个XML文档书写器</span><span style="color: #008000"><br /></span><span style="color: #000000">System.IO.StringWriter&nbsp;myStrWriter&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.IO.StringWriter();<br />System.Xml.XmlTextWriter&nbsp;myXMLWriter&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Xml.XmlTextWriter(&nbsp;myStrWriter&nbsp;);<br /></span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.IndentXML&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GenerateAtServer&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;myXMLWriter.Indentation&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">3</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;myXMLWriter.IndentChar&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;myXMLWriter.Formatting&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.Xml.Formatting.Indented&nbsp;;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;使用XML序列化将控件的树状节点全部保存到一个XML文档中并输出到XML文档书写器中</span><span style="color: #008000"><br /></span><span style="color: #000000">System.Xml.Serialization.XmlSerializer&nbsp;xser&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Xml.Serialization.XmlSerializer(&nbsp;</span><span style="color: #0000ff">typeof</span><span style="color: #000000">(&nbsp;SkyTreeNodeList&nbsp;));<br />xser.Serialize(&nbsp;myXMLWriter&nbsp;,&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Nodes&nbsp;);<br />myXMLWriter.Close();<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获得定义控件树状节点的XML字符串</span><span style="color: #008000"><br /></span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;xml&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;myStrWriter.ToString();</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">若控件的&#8220;</span>GenerateAtServer<span>&#8221;属性值为</span>true<span>，也就是在服务器端生成</span>HTML<span>代码，实现该功能的代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若在服务器端生成HTML代码则使用服务器端的XSLT转换<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;这里从资源文件SkyTreeViewControl.xslt中获得XSLT代码</span><span style="color: #008000"><br /></span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;xslt&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;ReadXSLTString();<br />System.Xml.XmlDocument&nbsp;xsltDocument&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Xml.XmlDocument();<br />xsltDocument.LoadXml(&nbsp;xslt&nbsp;);<br /><br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;获得树状节点的数据XML文档</span><span style="color: #008000"><br /></span><span style="color: #000000">System.Xml.XmlDocument&nbsp;NodeXmlDocument&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Xml.XmlDocument();<br />NodeXmlDocument.LoadXml(&nbsp;xml&nbsp;);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建一个字符串书写器，XSLT转换结果将输出到这个字符串书写器中</span><span style="color: #008000"><br /></span><span style="color: #000000">myStrWriter&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.IO.StringWriter();<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建XSLT转换引擎</span><span style="color: #008000"><br /></span><span style="color: #000000">System.Xml.Xsl.XslCompiledTransform&nbsp;transform&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Xml.Xsl.XslCompiledTransform();<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;引擎加载XSLT模板</span><span style="color: #008000"><br /></span><span style="color: #000000">transform.Load(xsltDocument);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;执行XSLT转换</span><span style="color: #008000"><br /></span><span style="color: #000000">transform.Transform(&nbsp;NodeXmlDocument&nbsp;&nbsp;,&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;,&nbsp;myStrWriter&nbsp;);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;直接向ASPX页面输出转换结果</span><span style="color: #008000"><br /></span><span style="color: #000000">writer.Write(&nbsp;myStrWriter.ToString());<br /></span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">这段代码中，首先调用函数</span>ReadXSLTString<span>从资源文件&#8220;</span>SkyTreeViewControl.xslt<span>&#8221;加载一个</span>XML<span>文档，然后创建一个</span>NodeXmlDocument<span>变量，调用它的</span>LoadXml<span>函数对根节点进行</span>XML<span>序列化所得的</span>XML<span>字符串来生成</span>XML<span>文档，然后创建一个</span>System.Xml.Xsl.XslCompiledTransform<span>类型的</span>XSLT<span>转换引擎，调用它的</span>Load<span>方法加载</span>XSLT<span>模板，调用它的</span>Transform<span>方法来执行</span>XSLT<span>转换，转换结果输出到</span>myStrWriter<span>的字符串书写器中，这个字符串书写器中的内容就是用于显示树状结构的</span>HTML<span>代码。然后程序使用</span>RenderContent<span>函数的</span>writer<span>参数将这个</span>HTML<span>代码输出到页面中。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>若不是在服务器端生成</span>HTML<span>代码，那就是在客户端生成代码了，于是程序输出一个</span>XML<span>数据岛的</span>HTML<span>代码，该数据岛的内容就是节点</span>XML<span>文档的内容。实现这个功能的</span>C#<span>代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;若在客户端动态生成HTML代码则将数据XML字符串输出到ASPX页面中</span><span style="color: #008000"><br /></span><span style="color: #000000">writer.Write(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;span&nbsp;id='</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ClientID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">_container'&nbsp;&gt;正在加载，请稍候<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&lt;/span&gt;</span><span style="color: #800000">"</span><span style="color: #000000">);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;将数据XML字符串输出到ASPX页面中的一个XML数据岛中</span><span style="color: #008000"><br /></span><span style="color: #000000">writer.Write(</span><span style="color: #800000">"</span><span style="color: #800000">&lt;xml&nbsp;id='</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ClientID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">_xml'&gt;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;xml&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&lt;/xml&gt;</span><span style="color: #800000">"</span><span style="color: #000000">);<br /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;输出将要初始化树状列表的JavaScript函数</span><span style="color: #008000"><br /></span><span style="color: #0000ff">this</span><span style="color: #000000">.Page.ClientScript.RegisterStartupScript(<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.GetType()&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">SkyTreeViewControL_Init_</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ClientID&nbsp;,&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000"><br />&lt;script&nbsp;language=javascript&gt;<br />RefreshSkyTreeViewControl(&nbsp;'</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ClientID&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000">'&nbsp;);<br />&lt;/script&gt;<br /></span><span style="color: #800000">"</span><span style="color: #000000">);</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">这里调用了</span>RegisterStartupScript<span>函数，使得</span>HTML<span>页面加载时立即调用名为</span> RefreshSkeyTreeViewControl <span>的</span>JavaScript<span>函数来初始化这个树状列表，本控件输出的第二段</span>HTML<span>代码就包含了该</span>JavaScript<span>函数。</span></p>
<h4><span>操作数据视图</span></h4>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>本</span>WEB<span>控件还在数据视图中保存数据，其功能代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;保存数据视图状态<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;returns&gt;</span><span style="color: #008000">操作结果</span><span style="color: #808080">&lt;/returns&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">object</span><span style="color: #000000">&nbsp;SaveViewState()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ViewState[</span><span style="color: #800000">"</span><span style="color: #800000">nodes</span><span style="color: #800000">"</span><span style="color: #000000">]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.myNodes&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.SaveViewState&nbsp;();<br />}<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;加载数据视图状态<br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;/summary&gt;</span><span style="color: #008000"><br /></span><span style="color: #808080">///</span><span style="color: #008000">&nbsp;</span><span style="color: #808080">&lt;param&nbsp;name="savedState"&gt;</span><span style="color: #008000">操作结果</span><span style="color: #808080">&lt;/param&gt;</span><span style="color: #808080"><br /></span><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">override</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;LoadViewState(</span><span style="color: #0000ff">object</span><span style="color: #000000">&nbsp;savedState)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;myNodes&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.ViewState[</span><span style="color: #800000">"</span><span style="color: #800000">nodes</span><span style="color: #800000">"</span><span style="color: #000000">]&nbsp;</span><span style="color: #0000ff">as</span><span style="color: #000000">&nbsp;SkyTreeNodeList&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">base</span><span style="color: #000000">.LoadViewState&nbsp;(savedState);<br />}</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">当</span>ASP.NET<span>框架要求</span>WEB<span>控件保存数据到视图中，系统会自动调用控件的</span>SaveViewState<span>函数，当</span>ASP.NET<span>框架要求</span>WEB<span>控件从数据视图中加载数据时，系统会自动调用</span>WEB<span>控件的</span>LoasViewState<span>函数。能保存在数据视图中的对象必须能进行二进制序列化。这就是在</span>SkyTreeNode<span>和</span>SkyTreeNodeList<span>类型前面都附加声明类型能进行二进制序列化的&#8220;</span>[System.<span style="color: #154857">Serializable()]</span><span>&#8221;的原因。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left">&nbsp;</p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>分析</span>SkyTreeViewControl<span>的源代码，读者可以看到这个</span>WEB<span>控件还是比较复杂的，它需要了解</span>ASP.NET<span>自定义控件的一些知识，此外还需要掌握</span>JavaScript<span>和</span>IE<span>浏览器</span>XML<span>数据岛的知识。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left">XML<span>数据岛是</span>IE<span>浏览器特有的功能，【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】是微软对</span>HTML<span>标准的扩展，其他浏览器是不支持</span>XML<span>数据岛的，实际上我们可以使用</span>XMLHttpRequest <span>的</span>ActiveX<span>组件来从服务器上下载</span>XML<span>文档，而</span>FireFox<span>是支持</span>XMLHttpRequest<span>的，这样可以做到对</span>FireFox<span>的兼容。在这里我特地演示使用了</span>XML<span>数据岛的功能，而且使用</span>XML<span>数据岛的功能能将</span>XML<span>文档嵌入到</span>HTML<span>文档中，减少</span>WEB<span>系统的文件数，从而降低系统复杂度，而且方便部署。若规定客户端浏览器限制为</span>IE<span>浏览器时，则可以采用</span>XML<span>数据岛的功能。</span></p>
<h3>SkyTreeViewControl.xslt</h3>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>这个</span>WEB<span>控件中有一个很重要的文档就是</span>XSLT<span>模板文档。它保存在文件</span>SkyTreeViewControl.xslt<span>中，并作为嵌入的资源参与程序的编译。这个</span>XSLT<span>模板文档的主体结构为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"&nbsp;</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:stylesheet&nbsp;</span><span style="color: #ff0000">xmlns:xsl</span><span style="color: #0000ff">="http://www.w3.org/1999/XSL/Transform"</span><span style="color: #ff0000">&nbsp;version</span><span style="color: #0000ff">="1.0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;和&nbsp;SkyTreeViewControl&nbsp;树状列表控件配合使用的XSLT文档，本文档的生成操作必须为&#8220;嵌入的资源&#8221;。<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;编制&nbsp;袁永福&nbsp;2008-1-29<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:output&nbsp;</span><span style="color: #ff0000">method</span><span style="color: #0000ff">="html"</span><span style="color: #ff0000">&nbsp;indent</span><span style="color: #0000ff">="no"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;*****************&nbsp;主模板，为XSLT转换的入口点&nbsp;********************&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:template&nbsp;</span><span style="color: #ff0000">match</span><span style="color: #0000ff">="/*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-------------&nbsp;主模板的内容&nbsp;-----------------------<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:template</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;*******************&nbsp;&nbsp;输出一个树状列表节点&nbsp;***************************&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:template&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TreeNode"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--------------&nbsp;子模板的内容&nbsp;----------------------<br />&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:template</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:stylesheet</span><span style="color: #0000ff">&gt;</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">这里使用了</span>xsl:output<span>指令</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 523.8pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="698">
<p align="left"><span style="font-family: 新宋体; color: blue; font-size: 10pt">&lt;</span><span style="font-family: 新宋体; color: #2b91af; font-size: 10pt">xsl:output</span> <span style="font-family: 新宋体; color: red; font-size: 10pt">method</span><span style="font-family: 新宋体; color: blue; font-size: 10pt">=</span><span style="font-family: 新宋体; font-size: 10pt">"<span style="color: blue">html</span>" <span style="color: red">indent</span><span style="color: blue">=</span>"<span style="color: blue">no</span>"<span style="color: blue"> /&gt;</span></span></p></td></tr></table>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>表明此</span>XSLT<span>转换生成是</span>HTML<span>代码，而且不进行缩进处理。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>该</span>XSLT<span>模板文档定义了两个</span>XSLT<span>模板，一个是默认模板，还有一个名为&#8220;</span>TreeNode<span>&#8221;的子模板。默认模板内容为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;*****************&nbsp;主模板，为XSLT转换的入口点&nbsp;********************&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:template&nbsp;</span><span style="color: #ff0000">match</span><span style="color: #0000ff">="/*"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义一个NodeID变量，表示当前节点的编号&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:variable&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="NodeID"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="string-length(&nbsp;@RootID&nbsp;)&nbsp;&gt;&nbsp;0&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="@RootID"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="string-length(ID)&nbsp;&gt;&nbsp;0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="ID"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="generate-id(&nbsp;.&nbsp;)&nbsp;"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:variable</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;若有子节点则显示子节点&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">table&nbsp;</span><span style="color: #ff0000">border</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;cellspacing</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;cellpadding</span><span style="color: #0000ff">="0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat(&nbsp;$NodeID&nbsp;,&nbsp;'_table'&nbsp;)&nbsp;"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:for-each&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="Node"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:call-template&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TreeNode"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:with-param&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Level"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">1</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:with-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:call-template</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:for-each</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">table</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:template</span><span style="color: #0000ff">&gt;</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">主模板是</span>XSLT<span>转换的入口处，在主模板中，首先创建了一个名为</span>NodeID<span>的</span>XSLT<span>参数，若定义了树状列表的根节点则创建</span>table<span>元素，然后循环遍历所有的根节点，并对每一个列表节点元素调用</span>TreeNode<span>模板，并传递了一个名为</span>Level<span>的值为</span>1<span>的参数，表示生成的节点层次数。这样就开始了递归创建</span>HTML<span>元素的过程。</span></p>
<h3>TreeNode <span>模板</span></h3>
<p style="text-align: left; text-indent: 21.3pt" align="left">TreeNode<span>模板是</span>XSLT<span>模板文档的主要部分，其代码为</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;*******************&nbsp;&nbsp;输出一个树状列表节点&nbsp;***************************&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:template&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TreeNode"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义一个&nbsp;Level&nbsp;参数，表示节点层次，默认&nbsp;0&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:param&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Level"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">0</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义一个NodeID变量，表示当前节点的编号&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:variable&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="NodeID"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="string-length(ID)&nbsp;&gt;&nbsp;0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="ID"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="generate-id(&nbsp;.&nbsp;)&nbsp;"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:variable</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;定义一个showChildNodes变量，表示当前节点是否默认显示子节点&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:variable&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ShowChildNode"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$Level&nbsp;&amp;lt;&nbsp;1&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">1</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:variable</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;获得所有子节点的个数&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:variable&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="ChildCount"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="count(Nodes/Node)&nbsp;"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:variable</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;判断是否存在子节点&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:variable&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="HasChild"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ChildCount&nbsp;&gt;&nbsp;0&nbsp;or&nbsp;string-length(&nbsp;XMLSource&nbsp;)&nbsp;&gt;&nbsp;0&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">1</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:variable</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;align</span><span style="color: #0000ff">="left"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;显示前面的树状结构线&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="&nbsp;$HasChild&nbsp;=&nbsp;'1'&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="position()!=last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="background"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_line.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat($NodeID,'_expend')"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ShowChildNode&nbsp;!=&nbsp;'1'&nbsp;and&nbsp;position()&nbsp;!=&nbsp;last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_collapse.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_expend.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ShowChildNode&nbsp;=&nbsp;'1'&nbsp;and&nbsp;position()&nbsp;!=&nbsp;last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_expend.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_collapse.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ShowChildNode&nbsp;!=&nbsp;'1'&nbsp;and&nbsp;position()&nbsp;=&nbsp;last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_lastcollapse.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_lastexpend.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ShowChildNode&nbsp;=&nbsp;'1'&nbsp;and&nbsp;position()&nbsp;=&nbsp;last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_lastexpend.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_lastcollapse.gif</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="onclick"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewContrlExpendNodeByID('</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="$NodeID"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">'&nbsp;,&nbsp;false&nbsp;);</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">img</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="position()!=last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">src</span><span style="color: #0000ff">="SkyTreeViewControl_child.gif"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="position()=last()"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">src</span><span style="color: #0000ff">="SkyTreeViewControl_lastchild.gif"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">td&nbsp;</span><span style="color: #ff0000">valign</span><span style="color: #0000ff">="top"</span><span style="color: #ff0000">&nbsp;nowrap</span><span style="color: #0000ff">="1"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;用于生成节点图标HTML代码&nbsp;&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">img&nbsp;</span><span style="color: #ff0000">align</span><span style="color: #0000ff">="absmiddle"</span><span style="color: #ff0000">&nbsp;width</span><span style="color: #0000ff">="16"</span><span style="color: #ff0000">&nbsp;height</span><span style="color: #0000ff">="16"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="onclick"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewContrlExpendNodeByID('</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="$NodeID"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">'&nbsp;,&nbsp;true&nbsp;);</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat($NodeID,'_icon')"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="string-length(&nbsp;Icon&nbsp;)&nbsp;!=&nbsp;0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="Icon"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="Icon"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$HasChild&nbsp;=&nbsp;'1'&nbsp;and&nbsp;$ShowChildNode&nbsp;=&nbsp;'1'"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_close.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_open.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:when&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$HasChild&nbsp;=&nbsp;'1'&nbsp;and&nbsp;$ShowChildNode&nbsp;!=&nbsp;'1'"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="SrcBack"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_open.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_close.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:when</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="src"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewControl_default.bmp</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:otherwise</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:choose</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">img</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;&nbsp;生成节点的文本&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a&nbsp;</span><span style="color: #ff0000">class</span><span style="color: #0000ff">="SkyTreeViewControl_TreeNode"</span><span style="color: #ff0000">&nbsp;valign</span><span style="color: #0000ff">="top"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat(&nbsp;$NodeID,&nbsp;'_text')"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="onclick"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">SkyTreeViewContrlExpendNodeByID('</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="$NodeID"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">'&nbsp;,&nbsp;true&nbsp;);</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="OnClick&nbsp;!=''"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="OnClick"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="Link&nbsp;!=&nbsp;''"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="href"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="Link"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="string-length(XMLSource)&nbsp;&gt;&nbsp;0&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="XMLSource"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">disable-output-escaping</span><span style="color: #0000ff">="yes"</span><span style="color: #ff0000">&nbsp;select</span><span style="color: #0000ff">="XMLSource"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat(&nbsp;'&nbsp;'&nbsp;,Text)"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ChildCount&nbsp;&gt;&nbsp;0&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;若有子节点则显示子节点&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">table&nbsp;</span><span style="color: #ff0000">border</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;cellspacing</span><span style="color: #0000ff">="0"</span><span style="color: #ff0000">&nbsp;cellpadding</span><span style="color: #0000ff">="0"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat(&nbsp;$NodeID&nbsp;,&nbsp;'_table'&nbsp;)&nbsp;"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="$ShowChildNode&nbsp;!=&nbsp;'1'"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="style"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">display:none</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:for-each&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="Nodes/Node"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;递归调用TreeNode模板本身来生成下一级的节点的HTML代码&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:call-template&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="TreeNode"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:with-param&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="Level"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;传递节点层次参数&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="$Level&nbsp;+&nbsp;1"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:with-param</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:call-template</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:for-each</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">table</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:if&nbsp;</span><span style="color: #ff0000">test</span><span style="color: #0000ff">="string-length(XMLSource)&nbsp;&gt;&nbsp;0&nbsp;"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">&lt;!--</span><span style="color: #008000">&nbsp;若节点的XMLSource存在则预先生成好&#8220;正在加载<img alt="" src="http://www.cnblogs.com/Images/dot.gif" />&#8221;字样，但隐藏起来&nbsp;</span><span style="color: #008000">--&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">span&nbsp;</span><span style="color: #ff0000">style</span><span style="color: #0000ff">='display:none'</span><span style="color: #ff0000">&nbsp;class</span><span style="color: #0000ff">='SkyTreeViewControl_TreeNode'</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:attribute&nbsp;</span><span style="color: #ff0000">name</span><span style="color: #0000ff">="id"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:value-of&nbsp;</span><span style="color: #ff0000">select</span><span style="color: #0000ff">="concat(&nbsp;$NodeID&nbsp;,&nbsp;'_Loading'&nbsp;)&nbsp;"</span><span style="color: #ff0000">&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:attribute</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">br&nbsp;</span><span style="color: #0000ff">/&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">正在加载<img alt="" src="http://www.cnblogs.com/Images/dot.gif" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:text</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">span</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:if</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">td</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">tr</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">xsl:template</span><span style="color: #0000ff">&gt;</span></div>
<p style="text-align: left; text-indent: 21.3pt" align="left">在这个模板中首先接受了一个名为</span>Level<span>的参数，该参数表示生成的树状列表的层次序号。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>此处定义了一个名为&#8220;</span>NodeID<span>&#8221;的</span>XSLT<span>变量，将作为树状列表节点在</span>HTML<span>文档中的编号。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>这里使用了</span>XSLT<span>函数</span>generate-id<span>，该函数属于创建一个惟一的编号。对相同的</span>XML<span>节点调用</span>generate-id<span>函数会得到相同的结果，对不同的</span>XML<span>节点调用该函数一定会得到不同的编号。注意，这里的编号在同一个</span>XML<span>文档中是惟一的，但对多个</span>XML<span>文档则不一定了。若对两个</span>XML<span>文档中的</span>XML<span>节点调用该函数是有可能得到相同的编号。因此当同一个页面上有多个</span>WEB<span>控件，或者</span>WEB<span>控件支持动态加载子节点时，【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】整个页面会对多个</span>XML<span>文档执行</span>XSLT<span>转换，从而导致多个节点对象可能使用一样的节点编号的情况。若多个节点的编号一样会导致树状列表工作异常。这就是为什么在本演示程序中的&#8220;</span>TreeViewNode.aspx<span>&#8221;中使用&#8220;</span>System.Guid.NewGuid<span>&#8221;来手动的设置节点编号的原因。因为&#8220;</span>NewGuid<span>&#8221;函数会创建一个全球惟一编号，多次调用&#8220;</span>NewGuid<span>&#8221;函数而创建相同的编号的可能性基本上不存在，这从而保证了同一个页面中所有树状列表的节点编号的惟一性。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>此处定义了名为&#8220;</span>ShowChildNode<span>&#8221;的</span>XSLT<span>变量。这里判断了</span>Level<span>参数值是否小于</span>1<span>，若小于</span>1<span>则参数值为</span>1<span>，表示初始化时该节点的子节点就显示出来。在这里可以控制树状列表初始化时显示多少层节点。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>此处定义了&#8220;</span>ChildCount<span>&#8221;变量，用于存放子节点的个数，以后需要获得子节点个数时就用这个变量，避免重复计算。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>此处定义了&#8220;</span>HasChild<span>&#8221;变量，用于判断是否有子节点，以后需要判断是否有子节点时就不需要重新计算了。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>准备工作完毕后开始输出</span>HTML<span>代码了。首先输出一个表格行，然后输出第一个单元格。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>若节点存在子节点，若节点不是父节点的最后一个子节点时设置单元格的背景图片，从而模拟显示树状列表的层次结构线。此外由于节点存在子节点，因此可以展开和收缩，因此还输出展开和收缩控制点，并对控制点图片添加&#8220;</span>onclick<span>&#8221;属性，该属性中调用了控件输出的第三段</span>HTML<span>代码中定义的名为&#8220;</span>SkyTreeViewContrlExpendNodeByID<span>&#8221;的</span>JavaScript<span>函数。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>若节点不存在子节点则输出图片来模拟树状结构叶子节点连接线。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>接下来就是输出第二个单元格了。首先输出节点前面的图标，若树状节点定义了</span>Icon<span>数据，则设置图标的</span>SrcBack<span>和</span>src<span>属性值为</span>Icon<span>数据。若没有指定</span>Icon<span>数据，则使用默认值。并设置显示图标的图片的&#8220;</span>onclick<span>&#8221;属性，这个&#8220;</span>onclick<span>&#8221;属性将会调用</span>JavaScript<span>函数&#8220;</span>SkyTreeViewContrlExpendNodeByID<span>&#8221;。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>然后输出节点文本，输出超链接和</span>OnClick<span>属性值，若节点还有</span>XMLSource<span>值，这设置该值到</span>HTML<span>元素的</span>XMLSource<span>属性中。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>系统判断</span>XSLT<span>变量&#8220;</span>ChildCount<span>&#8221;的值，若该节点存在子节点，则创建一个</span>table<span>元素，然后遍历所有的子节点，递归调用</span>TreeNode<span>模板，并传递</span>Level<span>参数，并使得</span>Level<span>参数值每次递归调用都增加１。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>若节点的</span>XMLSource<span>值有效，还输出一个隐藏的提示&#8220;正在加载&#8221;的文本标签。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left">&nbsp;</p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>经过上述过程，一种高性能的可动态加载子列表的</span>ASP.NET<span>树状列表控件开发完毕，接着笔者将这个</span>WEB<span>控件投入使用。</span></p>
<h3>Default.aspx</h3>
<p><span>演示程序中有一个</span>Default.aspx<span>页面，为默认页面，这个页面就演示使用树状列表</span>WEB<span>控件，读者可以使用</span>IE<span>浏览器运行这个页面，可以看到两个树状列表，都是使用了</span>3<span>层节点来显示数据库中的客户订单信息。</span></p>
<p><span>左边的列表内容是一下子加载了数据库中的所有的数据，页面加载后该树状列表已经包含了</span>3072<span>个节点。用户鼠标操作可以展开和收缩节点，可以点击货物节点来弹出一个消息框。</span></p>
<p><span>而右边的列表内容是动态加载的，页面加载后该列表只加载了客户信息，并没有加载定单信息和货物信息。当用户鼠标展开节点时，页面会根据需要自动的从后台加载相关的信息并动态的生成子节点。动态加载子节点能加快树状列表的初始化加载速度。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p><span>使用</span>VS.NET 2005<span>打开演示程序，重新编译一下，然后打开演示页面</span>Default.aspx <span>的设计界面。其设计界面如下图</span></p>
<p><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage014.jpg" width="684" height="470" /></p>
<p><span>可以看到页面上已经放置了两个树状列表控件。控件名为</span>myTreeView<span>和</span>myTreeView2<span>，鼠标点击某个树状列表控件，可以在旁边的属性窗口中列出了该控件的一些属性，其界面如下图所示，</span></p>
<p style="text-align: center; text-indent: 21pt" align="center"><img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/aspnettreeimage015.jpg" width="278" height="404" /></p>
<p><span>树状列表控件比较重要的属性有</span></p>
<p>AutoScroll <span>是否自动显示滚动条。</span></p>
<p>DynamicLoadChild<span>表示是否使用动态加载子节点。</span></p>
<p>GenerateAtServer <span>是否在服务器端生成</span>HTML<span>代码。</span></p>
<p>IndentXML <span>生成的</span>XML<span>是否进行缩进。</span></p>
<p>SelectedNodeStyleString <span>选中的节点的</span>CSS<span>样式字符串。</span></p>
<p>TreeNodeStyleString <span>节点的</span>CSS<span>样式字符串。</span></p>
<p><span>查看该页面的</span>HTML<span>代码，可以看到这里使用了标签&#8220;</span>SkyWebControl:SkyTreeViewControl<span>&#8221;来定义一个树状列表控件。一些控件的属性值保存在</span>HTML<span>标签的属性中。</span></p>
<p><span>一般的。</span>NET<span>框架中的</span>WEB<span>控件在</span>HTML<span>代码中的前缀是&#8220;</span>asp<span>&#8221;，比如&#8220;</span>asp:label<span>&#8221;，&#8220;</span>asp:button<span>&#8221;，&#8220;</span>asp:TextBox<span>&#8221;等。开发人员在开发自己的</span>WEB<span>控件也可以使用自己的</span>HTMJL<span>标签前缀，在树状列表控件的</span>C#<span>源代码中开头有一条指令</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 523.8pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="698">
<p>&nbsp;[assembly:System.Web.UI.<span style="color: #154857">TagPrefix(<span style="color: #a31515">"CS_Discovery"</span> , <span style="color: #a31515">"SkyWebControl"</span>)]</span></p></td></tr></table>
<p><span>这条指令就指明自定义控件采用什么样的标签前缀。</span></p>
<p><span>查看这个页面的</span>C#<span>代码，可以看到代码还是不复杂的。主要包含了一个</span>Page_Load<span>函数，该函数的代码为</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Page_Load(</span><span style="color: #0000ff">object</span><span style="color: #000000">&nbsp;sender,&nbsp;System.EventArgs&nbsp;e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;myTreeView.Nodes.Count&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;连接数据库</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">using</span><span style="color: #000000">(&nbsp;OleDbConnection&nbsp;conn&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;OleDbConnection())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.ConnectionString&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000">Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Server.MapPath(</span><span style="color: #800000">"</span><span style="color: #800000">SkyDemo.mdb</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.Open();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">using</span><span style="color: #000000">(&nbsp;OleDbCommand&nbsp;cmd&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;conn.CreateCommand())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;查询数据库,获得所有的客户名称、订单号和产品名称，<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;向树状列表myTreeView&nbsp;填充内容</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.CommandText&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000"><br />select<br />&nbsp;&nbsp;&nbsp;&nbsp;trim(Customers.CompanyName)&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;trim(orders.orderid&nbsp;&amp;&nbsp;chr(32)&nbsp;&amp;&nbsp;orders.shipname)&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;trim(products.productname)<br />from&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;customers&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;orders&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;orderdetails&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;products<br />where&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;customers.customerid&nbsp;=&nbsp;orders.customerid&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;orders.orderid&nbsp;=&nbsp;orderdetails.orderid<br />&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;orderdetails.productid&nbsp;=&nbsp;products.productid<br />order&nbsp;by&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;trim(Customers.CompanyName)&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;orders.orderid,<br />&nbsp;&nbsp;&nbsp;&nbsp;trim(products.productname)</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleDbDataReader&nbsp;reader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cmd.ExecuteReader();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;客户公司节点</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeNode&nbsp;CompanyNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;客户订单节点</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeNode&nbsp;OrderNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;reader.Read())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;读取客户公司名称</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;cname&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;读取订单编号和订货人名称</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;oname&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">1</span><span style="color: #000000">&nbsp;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;读取产品名称</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;pname&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">2</span><span style="color: #000000">&nbsp;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;CompanyNode&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;cname&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;CompanyNode.Text&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建新的客户公司节点并添加到控件myTreeView&nbsp;中</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OrderNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompanyNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SkyTreeNode();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompanyNode.Text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cname&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompanyNode.Icon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">customer.bmp</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myTreeView.Nodes.Add(&nbsp;CompanyNode&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;OrderNode&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;oname&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;OrderNode.Text&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建新的订单节点并添加到客户公司节点下</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OrderNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SkyTreeNode();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OrderNode.Text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;oname&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OrderNode.Icon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">order.bmp</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CompanyNode.Nodes.Add(&nbsp;OrderNode&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建新的货物节点并添加到订单节点下</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeNode&nbsp;ProductNode&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SkyTreeNode();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProductNode.Text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;pname&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProductNode.Icon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">product.bmp</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProductNode.OnClick&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">alert('</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;pname&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">')</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OrderNode.Nodes.Add(&nbsp;ProductNode&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000">//</span><span style="color: #008000">while</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Close();</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;树状列表myTreeView&nbsp;填充完毕<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;查询数据库获得所有的客户编号和客户名称，准备填充树状列表控件myTreeView2</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.CommandText&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">Select&nbsp;customerid&nbsp;,&nbsp;companyname&nbsp;from&nbsp;customers&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #800000">"</span><span style="color: #800000">&nbsp;order&nbsp;by&nbsp;companyname</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cmd.ExecuteReader();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;reader.Read())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建新的客户节点并添加到控件myTreeView2&nbsp;下。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;NodeID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.Guid.NewGuid().ToString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SkyTreeNode&nbsp;node&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SkyTreeNode();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.ID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;NodeID&nbsp;;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.Text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">1</span><span style="color: #000000">&nbsp;));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.Icon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">customer.bmp</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置节点的XMLSource属性准备客户端动态加载子节点<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;此处需要配合使用TreeViewNodeXml.aspx&nbsp;页面。</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.XMLSource&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">TreeViewNodeXml.aspx?KeyType=customerid&amp;KeyValue=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;)&nbsp;)&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myTreeView2.Nodes.Add(&nbsp;node&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Close();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000">//</span><span style="color: #008000">using</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000">//</span><span style="color: #008000">using</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.lblInfo.Text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">本控件共有节点</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;myTreeView.AllNodes.Count&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&nbsp;个</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.lblInfo2.Text&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">本控件初始化有</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;myTreeView2.AllNodes.Count<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&nbsp;个节点，能动态加载子节点</span><span style="color: #800000">"</span><span style="color: #000000">;<br />}</span></div>
<p>在这个函数中，首先连接程序目录下的演示数据库</span> SkyDemo.mdb<span>，然后执行一个比较复杂的</span>SQL<span>查询，获得数据库中所有的客户名称，订单信息和订单货物信息，然后填充到</span>myTreeView<span>的</span>Nodes<span>属性中，从而在内存中构造了一个三层的树状结构。</span></p>
<p><span>这里面可以看到树状列表没有自动的数据源绑定功能。由于树状结构处理过程复杂，简单的数据源绑定难于实现，因此这个树状列表控件不提供数据源绑定功能，而是需要使用者编程向列表添加节点。</span></p>
<p><span>填充第一个树状列表后，程序然后再次查询数据库，获得所有的客户名称和编号，然后填充到</span>myTreeView2 <span>的</span>Nodes<span>中，并设置每个节点的</span>XMLSource<span>属性。而</span>XMLSource<span>属性就规定了客户端动态加载子节点使用的</span>XML<span>文档的</span>URL<span>地址。这里使用了另外一个页面&#8220;</span>TreeViewNodeXml.aspx<span>&#8221;作为</span>XML<span>文档的提供者，并向该页面传递参数来决定生成什么样的节点定义</span>XML<span>文档。而且该页面生成的</span>XML<span>文档格式符合刚才设计的节点</span>XML<span>文档格式。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p><span>在这个页面中，没有任何生成</span>HTML<span>代码的代码，所做的只是向页面拖拽放置树状列表，然后查询数据库填充控件的节点结构，可以说使用比较方便，这个树状列表控件内部自动完成了所有的底层工作。</span></p>
<h3>TreeViewNodeXml.aspx </h3>
<p><span>本页面是一个后台服务页面，用于向第二个树状列表动态的提供子节点信息。该页面也不复杂，它没有</span>HTML<span>代码，其</span>ASPX<span>文件只有一行代码，其代码如下</span></p>
<table style="border-bottom: medium none; border-left: medium none; border-collapse: collapse; border-top: medium none; border-right: medium none" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="border-bottom: windowtext 1pt solid; border-left: windowtext 1pt solid; padding-bottom: 0cm; padding-left: 5.4pt; width: 523.8pt; padding-right: 5.4pt; border-top: windowtext 1pt solid; border-right: windowtext 1pt solid; padding-top: 0cm" valign="top" width="698">
<p align="left"><span style="font-family: 新宋体;background: yellow; font-size: 10pt">&lt;%</span><span style="font-family: 新宋体; color: blue; font-size: 10pt">@</span><span style="font-family: 新宋体; font-size: 10pt"> <span style="color: #a31515">Page</span> <span style="color: red">language</span><span style="color: blue">="c#"</span> <span style="color: red">Inherits</span><span style="color: blue">="CS_Discovery.TreeViewNodeXml"</span> <span style="color: red">CodeFile</span><span style="color: blue">="TreeViewNodeXml.aspx.cs"</span> <span style="background: yellow">%&gt;</span></span></p></td></tr></table>
<p><span>查看该页面的</span>C#<span>代码，只有一个</span>Page_Load<span>函数，其代码为</span></p>
<p><span></p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">protected</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;Page_Load(</span><span style="color: #0000ff">object</span><span style="color: #000000">&nbsp;sender,&nbsp;System.EventArgs&nbsp;e)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;关键字的类型</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;KeyType&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Request.QueryString[</span><span style="color: #800000">"</span><span style="color: #800000">KeyType</span><span style="color: #800000">"</span><span style="color: #000000">]&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;关键字的数值</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;KeyValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Request.QueryString[</span><span style="color: #800000">"</span><span style="color: #800000">KeyValue</span><span style="color: #800000">"</span><span style="color: #000000">];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置页面输出格式</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Response.ContentEncoding&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.Text.Encoding.GetEncoding(&nbsp;</span><span style="color: #800080">936</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Response.ContentType&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">text/xml</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;根据页面输出流创建XML文档书写器</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;System.Xml.XmlTextWriter&nbsp;writer&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Xml.XmlTextWriter(&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Response.Output&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;设置带缩进</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;writer.IndentChar&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #800000">&nbsp;</span><span style="color: #800000">'</span><span style="color: #000000">&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;writer.Indentation&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800080">3</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;writer.Formatting&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.Xml.Formatting.Indented&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;开始输出XML文档</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteStartDocument();<br />&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteStartElement(</span><span style="color: #800000">"</span><span style="color: #800000">Nodes</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;连接数据库</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">using</span><span style="color: #000000">(&nbsp;System.Data.OleDb.OleDbConnection&nbsp;conn&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;System.Data.OleDb.OleDbConnection())<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.ConnectionString&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000">Provider=Microsoft.Jet.OLEDB.4.0;Data&nbsp;Source=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.Server.MapPath(</span><span style="color: #800000">"</span><span style="color: #800000">SkyDemo.mdb</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.Open();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;查询数据库</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">using</span><span style="color: #000000">(&nbsp;System.Data.OleDb.OleDbCommand&nbsp;cmd&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;conn.CreateCommand())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(KeyType&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">customerid</span><span style="color: #800000">"</span><span style="color: #000000">)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;关键字为客户编号，则此时查询该客户编号下的所有的订单信息</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.CommandText&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">select&nbsp;orderid&nbsp;,&nbsp;shipname&nbsp;from&nbsp;orders&nbsp;where&nbsp;customerid='</span><span style="color: #800000">"</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;KeyValue&nbsp;</span><span style="color: #000000">+</span><span style="color: #800000">"</span><span style="color: #800000">'&nbsp;order&nbsp;by&nbsp;orderid</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Data.IDataReader&nbsp;reader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cmd.ExecuteReader();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;reader.Read())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteStartElement(</span><span style="color: #800000">"</span><span style="color: #800000">Node</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;NodeID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.Guid.NewGuid().ToString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;创建节点编号</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">ID</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,&nbsp;NodeID&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">Icon</span><span style="color: #800000">"</span><span style="color: #000000">,</span><span style="color: #800000">"</span><span style="color: #800000">order.bmp</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;节点文本就是订单编号和订单人姓名</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">Text</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;)&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">-</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">1</span><span style="color: #000000">&nbsp;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;输出生成子节点使用的XML文档URL地址，从功能上看相当于递归调用本页面</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">XMLSource</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">TreeViewNodeXml.aspx?KeyType=orderdetails&amp;KeyValue=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;))&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteEndElement();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(&nbsp;KeyType&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">orderdetails</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;关键字为订单编号，则此时查询该订单编号下的所有的货物的信息</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd.CommandText&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">@"</span><span style="color: #800000"><br />Select&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;products.productname&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;orderdetails.quantity&nbsp;<br />from&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;orderdetails&nbsp;,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;products&nbsp;<br />where&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;orderdetails.productid&nbsp;=&nbsp;products.productid&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;and&nbsp;orderdetails.orderid=</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;KeyValue&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">&nbsp;order&nbsp;by&nbsp;productname&nbsp;</span><span style="color: #800000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Data.IDataReader&nbsp;reader&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cmd.ExecuteReader();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">(&nbsp;reader.Read())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteStartElement(</span><span style="color: #800000">"</span><span style="color: #800000">Node</span><span style="color: #800000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">string</span><span style="color: #000000">&nbsp;NodeID&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.Guid.NewGuid().ToString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">ID</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,&nbsp;NodeID&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">Icon</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">product.bmp</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">Text</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;)));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteElementString(</span><span style="color: #800000">"</span><span style="color: #800000">OnClick</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">alert('</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;Convert.ToString(&nbsp;reader.GetValue(&nbsp;</span><span style="color: #800080">0</span><span style="color: #000000">&nbsp;))&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #800000">"</span><span style="color: #800000">')</span><span style="color: #800000">"</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteEndElement();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.Close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000">//</span><span style="color: #008000">using</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000">//</span><span style="color: #008000">using</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteEndElement();<br />&nbsp;&nbsp;&nbsp;&nbsp;writer.WriteEndDocument();<br />&nbsp;&nbsp;&nbsp;&nbsp;writer.Close();<br />}</span></div>
<p>这段代码过程也不复杂，首先获得名为</span>KeyType<span>和</span>KeyValue<span>的页面参数。然后在页面输出流上创建一个</span>XML<span>文档书写器，然后连接数据库准备查询数据。</span></p>
<p><span>若参数</span>KeyType<span>的值等于&#8220;</span>customerid<span>&#8221;，则表示</span>KeyValue<span>为一个客户编号，此时页面是要求输出输出该编号客户名下的所有的订单信息，此时代码连接数据库查询查询</span>Orders<span>数据表，对每一个查询记录输出一个名为</span>Node<span>的</span>XML<span>元素，使用</span>Guid.NewGuid()<span>创建一个不重复的节点编号，输出节点图标，文本信息。此外还输出</span>XMLSource<span>信息。这里的</span>XMLSource<span>信息表示订单节点的子节点信息来源，也就是指定订单的货品信息</span>XML<span>文档地址，这里还是指向页面</span>TreeViewNodeXml.aspx<span>，使用的</span>KeyType<span>参数值为</span>orderdetails<span>，而</span>KeyValue <span>参数值就是订单编号。</span></p>
<p><span>若页面参数</span>KeyType<span>的值等于</span>orderdetails<span>，则</span>KeyValue<span>为一个订单编号，此时页面被要求输指定编号的订单中的详细货物清单，此时程序执行一个简单的联合查询，获得指定订单编号的所有货品信息，然后输出</span>XML<span>文档。由于货品信息没有子节点，因此也就不输出</span>XMLSource<span>元素了。</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left">&nbsp;</p>
<h3><span>其他文件</span></h3>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>这个树状列表控件还包含了一些其他文件，比如</span>SkyTreeViewControl.bmp<span>是控件在</span>VS.NET<span>窗体设计器工具箱上显示的小图标。而其他的以　</span>SkyTreeViewControl_<span>开头的图片文件用于模拟显示树状列表的层次结构，还有一些默认图标文件。</span></p>
<h3><span>其他说明</span></h3>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>读者可以试着运行演示页面</span>Default.aspx<span>，可以发现对树状控件进行不同的设置，生成的</span>HTML<span>页面大小是不相同的。比如笔者设置左边的列表的</span>GenerateAtServer<span>属性为</span>false<span>，</span>IndentXML<span>为</span>false<span>时，也就是启动客户端生成</span>HTML<span>代码，则生成的客户端加载的</span>HTML<span>页面大小为三百多</span>K<span>，查看其</span>HTML<span>源代码，发现树状列表的节点</span>XML<span>文档占据着</span>HTML<span>文档的大部分。若笔者设置左边的列表的</span>GenerateAtServer<span>属性为</span>true<span>，也就是在服务器端生成</span>HTML<span>代码，则客户端显示的</span>HTML<span>页面大小接近</span>2<span>兆。体积瞬间增长到</span>6<span>倍，也就是说当树状列表节点比较多时（这里有三千多个），则在服务器端生成代码和在客户端生成代码这两种模式存在很大的差别。这是因为当在客户端生成代码时，服务器端向客户端发送的是</span>XML<span>文档，只包含比较纯粹的数据，体积小；而在服务器端生成代码时，服务器端发送的是</span>HTML<span>代码，除了包含数据外，还有大量的用于控制界面样式的</span>HTML<span>代码，这导致</span>HTML<span>代码量大。【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p style="text-align: left; text-indent: 21.3pt" align="left"><span>在以前的</span>XML/XSLT<span>章节中，笔者提过，在</span>WEB<span>开发中采用</span>XML/XSLT<span>技术能比较大的改善</span>WEB<span>程序的网络传输性能，在这里用于显示大量节点的树状列表的应用就是一个范例。</span></p>
<h2><span style="font-family: 黑体">部署控件</span></h2>
<p><span>这个树状列表控件开发完毕后包含在一个</span>DLL<span>文件中，编译程序前要注意设置文件&#8220;</span>SkyTreeViewControl.bmp<span>&#8221;和&#8220;</span>SkyTreeViewControl.xslt<span>&#8221;的&#8220;生成操作&#8221;属性值为&#8220;嵌入的资源&#8221;。</span></p>
<p><span>开发人员在开发其他系统时可以添加这个</span>DLL<span>的引用，在</span>VS.NET<span>的窗体设计器的工具箱上可以看到这个树状列表的图标，若没有则在工具箱上右击显示快捷菜单，选中&#8220;添加／移除项目&#8221;，在对话框中选择浏览，显示包含控件的</span>DLL <span>文件，然后选择</span>SkyTreeViewControl<span>即可。</span></p>
<p><span>开发人员从工具箱中拖拽一个树状列表控件到</span>ASP.NET<span>页面上就可以开始使用了。</span></p>
<p><span>在开发和部署包含树状列表的</span>WEB <span>程序前，需要将所有&#8220;</span>SkyTreeViewControl_<span>&#8221;前缀的图片文件拷贝到程序第一级目录下。</span></p>
<h2><span style="font-family: 黑体">小结</span></h2>
<p><span>在本章中，大家一起研究了目前一些</span>ASP.NET<span>项目中使用的树状列表的原理和出现的问题，并开发新的树状列表控件。这种</span>WEB<span>树状列表控件支持在客户端和服务器端使用</span>XSLT<span>技术生成</span>HTML<span>代码，并能在客户端动态加载子列表，相对于旧控件，新控件加载速度快，能显示大量的节点。</span></p>
<p><span>此外读者还学习了</span>IE<span>浏览器所特有的</span>XML<span>数据岛的功能，并使用</span>JavaScript<span>脚本在客户端执行</span>XSLT<span>转换。这里读者可以看到</span>XSLT<span>技术作为国际标准技术已经得到广泛的支持。<br />【袁永福原创(<a href="http://www.xdesigner.cn/">http://www.xdesigner.cn/</a>),请尊重知识】</span></p>
<p>&nbsp;</p> <img src="http://www.cnblogs.com/xdesigner/aggbug/1570497.html?type=1" width="1" height="1" alt=""/><p>评论: 9　<a href="http://www.cnblogs.com/xdesigner/archive/2009/09/20/asp_net_treeview.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/09/20/asp_net_treeview.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>C#发现之旅第十四讲 基于动态编译的VB.NET脚本引擎</title><link>http://www.cnblogs.com/xdesigner/archive/2009/07/27/1531742.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Mon, 27 Jul 2009 01:39:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/07/27/1531742.html</guid><description><![CDATA[<p>阅读: 1943 评论: 2 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-07-27 09:39 <a href="http://www.cnblogs.com/xdesigner/archive/2009/07/27/1531742.html" target="_blank">原文链接</a></p><h2><span style="font-family: 黑体">本章说明</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在前面章节中，笔者使用了反射和动态编译技术实现了快速</span>ORM<span style="font-family: 宋体">框架，在本章中笔者将继续使用这些技术来实现一个</span>VB.NET<span style="font-family: 宋体">的脚本引擎，使得人们在开发中能实现类似</span>MS Office<span style="font-family: 宋体">那样实现</span>VBA<span style="font-family: 宋体">宏的功能。本章配套的演示程序为<a href="http://files.cnblogs.com/xdesigner/MyVBAScript.zip">/Files/xdesigner/MyVBAScript.zip</a>.</span></p>
<h2><span style="font-family: 黑体">脚本的原理</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">脚本，也可称为宏，是一种应用系统二次开发的技术，它能在应用系统提供的一个容器环境中运行某种编程语言，这种编程语言代码调用应用系统提供的编程接口，使得应用系统暂时&#8220;灵魂附体&#8221;，无需用户干预作而执行一些自动的操作，此时应用系统称为&#8220;宿主&#8221;。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">脚本也采用多种编程语言，比如</span>JavaScript<span style="font-family: 宋体">语言，</span>VBScript<span style="font-family: 宋体">语言或者其他的，若采用</span>VB<span style="font-family: 宋体">则称为</span>VB<span style="font-family: 宋体">脚本。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">下图为脚本原理图</span></p>
<p style="text-indent: 21pt" align="center"></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="245" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/script-theory.gif" width="335" border="0" /><br />下图为常规编程开发软件的原理图<br /></span></p>
<p style="text-indent: 21pt" align="center"></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="234" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/script-normal.gif" width="474" border="0" /><br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp; 脚本相对于常规的软件开发用的编程语言有着很大的不同。首先是脚本是不能独立运行的，必须在某个应用系统搭建的容器环境中运行，脱离这个环境则脚本代码毫无作用，其逻辑和功能和应用系统的功能联系非常紧密。脚本代码不会事先编译，而是解释执行或者临时编译执行的，而且脚本代码的修改不会导致应用系统的重新编译和部署，而且脚本代码发生修改，应用系统不需要重新启动即可应用修改后的脚本代码，而且运行脚本的应用系统可以不是</span>DLL<span style="font-family: 宋体">，而是纯粹的</span>EXE<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">脚本语言大多是动态语言，所谓动态语言就是程序代码在编写时已经假设操作的对象的类型，成员属性或方法的信息，而编译器不会进行这方面的检查。</span>C#<span style="font-family: 宋体">不是动态语言，是静态语言，因为它在编译时会严格的检查代码操作的对象的类型，成员信息，稍有不对则会报编译错误。</span>VB.NET<span style="font-family: 宋体">源自</span>VB<span style="font-family: 宋体">，是动态语言，它在编译时不会严格的检查对象的类型及其成员信息，执行后期绑定，而是在运行时检查，若运行时发现对象类型和成员信息错误，则会报运行时错误。脚本技术应当非常灵活和自由，袁某人觉得此时使用</span>C#<span style="font-family: 宋体">这种静态语言不是明智之举，而应当使用类似</span>VB.NET<span style="font-family: 宋体">这样的动态语言。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">而常规的软件开发而生成的软件大多是事先编译好的，和应用系统是独立的，软件是调用应用系统的功能而不是应用系统的一部分。软件代码修改会导致软件的重新编译和部署，应用系统必须提供</span>DLL<span style="font-family: 宋体">格式的程序集文件。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">微软的很多软件产品有有</span>VBA<span style="font-family: 宋体">的功能，比如</span>MS Office<span style="font-family: 宋体">，甚至</span>VS.NET<span style="font-family: 宋体">集成开发环境也有</span>VBA<span style="font-family: 宋体">宏的功能。脚本提供给应用系统二次开发的能力，而且这种二次开发能力简单灵活，部署方便。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在应用方面脚本技术带来的最大好处就是简单灵活，部署方便。脚本代码以纯文本的格式进行存储，修改方便，而且脚本修改后，应用系统无需重新启动而能立即使用新的脚本，脚本代码中能实现比较复制的逻辑控制，能响应应用系统的事件，能一定程度上扩展应用系统的功能，这有点类似数据库中的存储过程。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">但脚本功能运行在应用系统提供的容器环境中，其功能是受到严格限制的，一些脚本还受到系统权限的限制。因此脚本只能有限的扩展应用系统的功能，若所需功能比较复杂，脚本可能无法实现，此时还得依赖传统编程。不过在很多情况下，脚本还是能发挥很大的作用。【袁永福原创，转载请注明出处】</span></p>
<h2>VB.NET<span style="font-family: 黑体">脚本原理</span></h2>
<p style="text-indent: 21pt">VB.NET<span style="font-family: 宋体">脚本就是采用</span>VB.NET<span style="font-family: 宋体">语法的脚本。</span>VS.NET<span style="font-family: 宋体">集成开发环境提供的宏也是采用</span>VB.NET<span style="font-family: 宋体">语法。微软</span>.NET<span style="font-family: 宋体">框架提供了一个脚本引擎，那就是在程序集</span>microsoft.visualbasic.vsa.dll<span style="font-family: 宋体">中的类型</span>Microsfot.VisualBasic.Vsa.VsaEngine<span style="font-family: 宋体">，该类型在微软</span>.NET<span style="font-family: 宋体">框架</span>1.1<span style="font-family: 宋体">和</span>2.0<span style="font-family: 宋体">中都有，使用起来不算容易，而且在微软</span>.NET<span style="font-family: 宋体">框架</span>2.0<span style="font-family: 宋体">中</span>VsaEngine<span style="font-family: 宋体">类型标记为&#8220;已过时&#8221;。在此笔者不使用</span>VsaEngine<span style="font-family: 宋体">类型来实现</span>VB.NET<span style="font-family: 宋体">脚本，而是使用动态编译技术来实现脚本引擎。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">使用动态编译技术实现</span>VB.NET<span style="font-family: 宋体">脚本引擎的原理是，程序将用户的脚本代码字符串进行一些预处理，然后调用</span>Microsoft.VisualBasic.VBCodeProvider<span style="font-family: 宋体">类型的</span>CompileAssemblyFromSource<span style="font-family: 宋体">函数进行动态编译，生成一个临时的程序集对象，使用反射技术获得程序集中的脚本代码生成的方法，主程序将按照名称来调用这些脚本代码生成的方法。若用户修改了脚本代码，则这个过程重复一次。</span></p>
<h2>VB.NET<span style="font-family: 黑体">脚本引擎设计</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里笔者将用倒推法来设计</span>VB.NET<span style="font-family: 宋体">脚本引擎，也就是从预期的最终使用结果来反过来设计脚本引擎。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">主程序将按照名称来调用脚本方法，很显然</span>VB.NET<span style="font-family: 宋体">代码编译生成的是一个</span>.NET<span style="font-family: 宋体">程序集类库，为了方便起见，笔者将所有的</span>VB.NET<span style="font-family: 宋体">脚本方法集中到一个</span>VB.NET<span style="font-family: 宋体">脚本类型。笔者将脚本方法定义为静态方法，主要有两个好处，首先脚本引擎不必生成对象实例，其次能避免由于没有生成对象实例而导致的空引用错误，这样能减少脚本引擎的工作量。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在</span>VB.NET<span style="font-family: 宋体">语法中，可以使用代码块&#8220;</span>public shared sub SubName()<span style="font-family: 宋体">&#8221;来定义一个静态过程，但笔者不能要求用户在编写</span>VB.NET<span style="font-family: 宋体">脚本代码时使用&#8220;</span>public shared sub SubName()<span style="font-family: 宋体">&#8221;的</span>VB.NET<span style="font-family: 宋体">语法，而只能使用&#8220;</span>sub SubName()<span style="font-family: 宋体">&#8221;这样比较简单的语法。同样用户在脚本中定义全局变量时不能使用&#8220;</span>private shared VarName as TypeName<span style="font-family: 宋体">&#8221;的语法，而是简单的使用&#8220;</span>dim VarName as TypeName<span style="font-family: 宋体">&#8221;的语法。这时笔者可以使用</span>VB.NET<span style="font-family: 宋体">语法的模块的概念。在</span>VB.NET<span style="font-family: 宋体">语法中，将代码块&#8220;</span>Module ModuleName &#8230;&#8230;. End Module<span style="font-family: 宋体">&#8221;中的所有的代码编译为静态的。比如把&#8220;</span>sub SubName<span style="font-family: 宋体">&#8221;编译成&#8220;</span>public shared sub SubName()<span style="font-family: 宋体">&#8221;，把&#8220;</span>dim VarName as TypeName<span style="font-family: 宋体">&#8221;编译为&#8220;</span>public shared VarName as TypeName<span style="font-family: 宋体">&#8221;。这样借助</span>VB.NET<span style="font-family: 宋体">模块的概念就能解决了这个问题。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在一些脚本中笔者经常可以看见类似&#8220;</span>window.left<span style="font-family: 宋体">&#8221;或者&#8220;</span>document.location<span style="font-family: 宋体">&#8221;的方式来使用全局对象，若笔者在</span>VB.NET<span style="font-family: 宋体">中直接使用&#8220;</span>window.left<span style="font-family: 宋体">&#8221;之类的代码必然报&#8220;</span>window<span style="font-family: 宋体">&#8221;对象或者变量找不到的编译错误。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">&#8220;</span>window<span style="font-family: 宋体">&#8221;全局变量一般映射到应用程序的主窗体。比如&#8220;</span>window.left<span style="font-family: 宋体">&#8221;表示主窗体的左端位置，&#8220;</span>window.width<span style="font-family: 宋体">&#8221;标准主窗体的宽度等等。【袁永福原创，转载请注明出处】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">&#8220;</span>document<span style="font-family: 宋体">&#8221;或者&#8220;</span>window<span style="font-family: 宋体">&#8221;等全局对象是映射到文档或者主窗体等实例对象的，因此它们的成员不能定义成静态，为了能实现在脚本代码中直接使用类似&#8220;</span>window.left<span style="font-family: 宋体">&#8221;的方法来直接使用全局对象，笔者又得使用</span>VB.NET<span style="font-family: 宋体">的一个语法特性。在</span>Microsoft.VisualBasic.dll<span style="font-family: 宋体">中有一个公开的特性类型&#8220;</span>Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute<span style="font-family: 宋体">&#8221;，该特性是隐藏的，可能不是微软推荐使用，但在微软</span>.NET<span style="font-family: 宋体">框架</span>1.1<span style="font-family: 宋体">和</span>2.0<span style="font-family: 宋体">都有这个特性类型，功能也是一样的。对于一般的编程该特性是用不着的，它可附加在某个类型上，</span>VB.NET<span style="font-family: 宋体">编译器会认为附加了该特性的类型的静态属性值就是全局对象。比如笔者定义了一个</span>GlobalObject<span style="font-family: 宋体">类型，附加了</span>StandardModuleAttribute<span style="font-family: 宋体">特性，它有一个名为</span>Document<span style="font-family: 宋体">的静态属性，在对于脚本中的&#8220;</span>document.Location<span style="font-family: 宋体">&#8221;代码块，</span>VB.NET<span style="font-family: 宋体">编译器会针对&#8220;</span>document<span style="font-family: 宋体">&#8221;标识符检索所有附加了</span>StandardModuleAttribute<span style="font-family: 宋体">的类型的静态属性，最后命中</span>GlobalObject<span style="font-family: 宋体">类型，于是会自动扩展为&#8220;</span>GlobalObject.Document.Location<span style="font-family: 宋体">&#8221;的代码。这个过程是在编译时进行的，在实际运行中不再需要进行这样的查找，这样的语法特点是</span>C#<span style="font-family: 宋体">所没有的。上述的这些特点使得</span>VB.NET<span style="font-family: 宋体">语法更适合作为脚本的语法。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类似全局对象，在</span>VB.NET<span style="font-family: 宋体">语法中具有全局函数的功能，比如对于</span>Asc<span style="font-family: 宋体">函数，它实际上是类型</span>Microsoft.VisualBasic.Strings<span style="font-family: 宋体">的一个静态成员函数，但在</span>VB.NET<span style="font-family: 宋体">中可以在任何时候任何地方直接使用，</span>VB.NET<span style="font-family: 宋体">编译器会将代码中的</span>Asc<span style="font-family: 宋体">函数自动扩展为&#8220;</span>Microsoft.VisualBasic.Strings.Asc<span style="font-family: 宋体">&#8221;。这个过程是在编译时进行的，而运行时不再需要这样的扩展。</span></p>
<p style="text-indent: 21pt">.NET<span style="font-family: 宋体">框架自带</span>VB.NET<span style="font-family: 宋体">编译器，它就是在</span>.NET<span style="font-family: 宋体">框架安装目录下的</span>vbc.exe<span style="font-family: 宋体">，在笔者的系统中</span>VB.NET<span style="font-family: 宋体">编译器的路径是&#8220;</span>C:"WINDOWS"Microsoft.NET"Framework"v2.0.50727"vbc.exe<span style="font-family: 宋体">&#8221;，参考</span>MSDN<span style="font-family: 宋体">中关于</span>VB.NET<span style="font-family: 宋体">编译的命令行的说明，它支持一个名为&#8220;</span>imports<span style="font-family: 宋体">&#8221;的命令行参数指令。比如可以这样调用</span>VB.NET<span style="font-family: 宋体">编译器&#8220;</span>vbc.exe /imports:Microsoft.VisualBasic,system,system.drawing <span style="font-family: 宋体">其他参数&#8221;，该参数的功能是从指定的程序集导入名称空间。在</span>VB.NET<span style="font-family: 宋体">编译器命令行中使用</span>imports<span style="font-family: 宋体">指令和在</span>VB.NET<span style="font-family: 宋体">代码中使用</span>Imports<span style="font-family: 宋体">指令是不一样的。在源代码中使用</span>Imports<span style="font-family: 宋体">指令是用于减少代码编写量，而在命令行中使用</span>imports<span style="font-family: 宋体">指令是启动指定名称空间下的全局对象和全局函数，若一个类型附加了</span>StandardModuleAttribute<span style="font-family: 宋体">特性，而且定义了一些静态函数和属性，但并没有在编译器命令行中导入带类型所在的名称空间，则</span>VB.NET<span style="font-family: 宋体">编译器不会感知到该类型中定义的全局对象和全局函数，因此在编写</span>VB.NET<span style="font-family: 宋体">代码时必须使用&#8220;类型名称</span>.<span style="font-family: 宋体">静态属性或函数的名称&#8221;的方式来调用全局对象和全局函数。比如若没有在</span>VB.NET<span style="font-family: 宋体">编译器的命令行参数中使用&#8220;</span>/imports:Microsoft.VisualBasic<span style="font-family: 宋体">&#8221;参数，则</span>Asc<span style="font-family: 宋体">函数不再是全局函数，若在代码中直接使用</span>Asc<span style="font-family: 宋体">函数则必然报编译错误，而必须使用&#8220;</span>Microsoft.VisualBasic.Strings.Asc<span style="font-family: 宋体">&#8221;的方式来使用，即使源代码中使用了&#8220;</span>Imports Microsoft.VisualBasic<span style="font-family: 宋体">&#8221;，也只能用&#8220;</span>Strings.Asc<span style="font-family: 宋体">&#8221;的方式来使用函数。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">如上所述，借助于</span>StandardModuleAttribute<span style="font-family: 宋体">特性和编译器命令行参数</span>imports<span style="font-family: 宋体">，笔者就可以实现</span>VB.NET<span style="font-family: 宋体">的全局对象和全局函数了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">根据上述说明，笔者设计如下的参与动态编译的</span>VB.NET<span style="font-family: 宋体">脚本代码的结构</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">Option</span> Strict Off</p>
<p>Imports System</p>
<p>Imports Microsoft.VisualBasic</p>
<p>Namespace NameSpaceXVBAScriptEngien</p>
<p><span>&nbsp;&nbsp;&nbsp; Module mdlXVBAScriptEngine</span></p>
<p><em>&nbsp;</em></p>
<p><em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">sub</span> 脚本方法1()</span></em></p>
<p><em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">'VB.NET代码</span></span></em></p>
<p><em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">end</span> <span style="color: blue">sub</span></span></em></p>
<p><em>&nbsp;</em></p>
<p><em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">sub</span> 脚本方法2()</span></em></p>
<p><em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">'VB.NET代码</span></span></em></p>
<p><em><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">end</span> <span style="color: blue">sub</span></span></em></p>
<p><em>&nbsp;</em></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">End</span> Module</span></p>
<p><span style="color: blue">End</span> Namespace</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">其中斜体部分就是用户提供的原始脚本代码，而开头和结尾部分是脚本引擎自动添加的，这样能减少脚本引擎的使用难度。【袁永福原创，转载请注明出处】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在脚本引擎自动添加的代码中使用了</span>Imports<span style="font-family: 宋体">语句引入的名称空间，默认添加了</span>System<span style="font-family: 宋体">和</span>Microsoft.VisualBasic<span style="font-family: 宋体">两个名称空间，为了方便使用，可以让用户添加其他的名称空间，比如脚本代码中大量使用了</span>System.Drawing<span style="font-family: 宋体">名称空间，则可以使用</span>Imports<span style="font-family: 宋体">语句导入</span>System.Drawing<span style="font-family: 宋体">名称空间来减少脚本代码量。</span></p>
<h2><span style="font-family: 黑体">软件开发</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者新建一个</span>XVBAEngine<span style="font-family: 宋体">类型，该类型实现了脚本引擎的功能。脚本引擎包含了参数控制属性，代码生成器，动态编译，分析和调用临时程序集等几个子功能。</span></p>
<h3><span style="font-family: 宋体">参数控制属性</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者为脚本引擎类型定义了几个属性用于保存脚本引擎运行所必备的基础数据。这些属性中最重要的属性就是用户设置的原始脚本代码文本。定义该属性的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 脚本代码改变标记</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">bool bolScriptModified = <span style="color: blue">true</span>;</span></p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 原始的VBA脚本文本</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">string strScriptText = <span style="color: blue">null</span>;</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 原始的VBA脚本文本</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">string ScriptText</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> strScriptText;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp; &nbsp;<span style="color: blue">set</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (strScriptText != <span style="color: blue">value</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolScriptModified = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strScriptText = <span style="color: blue">value</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这里</span>ScriptText<span style="font-family: 宋体">属性表示用户设置的原始的</span>VBA<span style="font-family: 宋体">脚本代码，实际参与动态编译的脚本代码和原始设置的原始的</span>VBA<span style="font-family: 宋体">脚本代码是不一致的。当用户修改了脚本代码文本，则会设置</span>bolScriptModified<span style="font-family: 宋体">变量的值，脚本引擎运行脚本方法时会检查这个变量的值来判断是否需要重新动态编译操作。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">此外袁某人还定义了其他的一些控制脚本引擎的属性，其定义的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">private</span> <span style="color: blue">bool bolEnabled = <span style="color: blue">true</span>;</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 对象是否可用</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">bool Enabled</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> bolEnabled;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolEnabled = <span style="color: blue">value</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: blue">private</span> <span style="color: blue">bool bolOutputDebug = <span style="color: blue">true</span>;</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 脚本在运行过程中可否输出调试信息</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">bool OutputDebug</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> bolOutputDebug;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolOutputDebug = <span style="color: blue">value</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">&nbsp;</p>
<h3><span style="font-family: 宋体">编译脚本</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者为脚本引擎编写了</span>Compile<span style="font-family: 宋体">函数用于编辑脚本。编译脚本的过程大体分为生成脚本代码文本、编译脚本编译、分析脚本程序集三个步骤。</span></p>
<h4><span style="font-family: 宋体">生成脚本代码文本</span></h4>
<p style="text-indent: 21pt">VB.NET<span style="font-family: 宋体">脚本引擎使用的动态编译技术，而动态编译技术的第一个部分就是代码生成器，脚本大部分代码都是由主程序提供的，因此其代码生成器也就是将原始的脚本代码进行一些封装而已。【袁永福原创，转载请注明出处】</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">根据上述对运行时脚本的设计，用户可以导入其他的名称空间，于是脚本引擎定义了</span>SourceImports<span style="font-family: 宋体">属性来自定义导入的名称空间，定义该属性的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 源代码中使用的名称空间导入</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: #154857">StringCollection mySourceImports = <span style="color: blue">new</span> <span style="color: #154857">StringCollection</span>();</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 源代码中使用的名称空间导入</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: #154857">StringCollection SourceImports</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> mySourceImports;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在脚本引擎的初始化过程中，程序会默认添加上</span>System<span style="font-family: 宋体">和</span>Microsoft.VisualBasic<span style="font-family: 宋体">两个名称空间。随后程序使用以下代码来生成实际参与编辑的脚本代码文本</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>// 生成编译用的完整的VB源代码</p>
<p><span style="color: blue">string</span> ModuleName = <span style="color: #a31515">"mdlXVBAScriptEngine";</span></p>
<p><span style="color: blue">string</span> nsName = <span style="color: #a31515">"NameSpaceXVBAScriptEngien";</span></p>
<p>System.Text.<span style="color: #154857">StringBuilder mySource = <span style="color: blue">new</span> System.Text.<span style="color: #154857">StringBuilder</span>();</span></p>
<p>mySource.Append(<span style="color: #a31515">"Option Strict Off");</span></p>
<p><span style="color: blue">foreach</span> (<span style="color: blue">string import <span style="color: blue">in</span> <span style="color: blue">this</span>.mySourceImports)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; mySource.Append(<span style="color: #a31515">""r"nImports "</span> + import);</span></p>
<p>}</p>
<p>mySource.Append(<span style="color: #a31515">""r"nNamespace " + nsName);</span></p>
<p>mySource.Append(<span style="color: #a31515">""r"nModule " + ModuleName);</span></p>
<p>mySource.Append(<span style="color: #a31515">""r"n");</span></p>
<p>mySource.Append(<span style="color: blue">this.strScriptText);</span></p>
<p>mySource.Append(<span style="color: #a31515">""r"nEnd Module");</span></p>
<p>mySource.Append(<span style="color: #a31515">""r"nEnd Namespace");</span></p>
<p><span style="color: blue">string</span> strRuntimeSource = mySource.ToString();</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这段代码功能也比较简单，首先输出&#8220;</span>Option Strick Off<span style="font-family: 宋体">&#8221;语句，然后使用</span>mySourceImports<span style="font-family: 宋体">输出若干个</span>Imports<span style="font-family: 宋体">语句。这里的</span>mySourceImports<span style="font-family: 宋体">是一个字符串列表，用于存放引用的名称空间，比如&#8220;</span>System<span style="font-family: 宋体">&#8221;，&#8220;</span>Microsoft.VisualBasic<span style="font-family: 宋体">&#8221;等等，用于组成</span>VB.NET<span style="font-family: 宋体">脚本的</span>Imports<span style="font-family: 宋体">语句。然后输出</span>Namespace<span style="font-family: 宋体">和</span>Module<span style="font-family: 宋体">代码块来包括了用户提供的原始代码文本。这里的</span>strSourceText<span style="font-family: 宋体">就是用户提供的原始代码文本。最后变量</span> strRuntimeSource<span style="font-family: 宋体">中就包含了实际运行的</span>VB.NET<span style="font-family: 宋体">代码文本。【袁永福原创，转载请注明出处】</span></p>
<h4><span style="font-family: 宋体">编译脚本</span></h4>
<p style="text-indent: 21pt"><span style="font-family: 宋体">程序生成完整的</span>VB.NET<span style="font-family: 宋体">脚本代码文本后就可以编译了，为了提高效率，这里袁某定义了一个静态</span>myAssemblies<span style="font-family: 宋体">的哈希列表变量，定义该变量的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 所有缓存的程序集</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">static <span style="color: #154857">Hashtable</span> myAssemblies = <span style="color: blue">new</span> <span style="color: #154857">Hashtable</span>();</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该列表缓存了以前编辑生成的程序集，键值就是脚本文本，键值就是程序集。若缓存区中没有找到以前缓存的程序集那脚本引擎就可以调用</span>VB.NET<span style="font-family: 宋体">编译器编辑脚本了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了丰富脚本引擎的开发接口，笔者使用以下代码定义了</span>ReferencedAssemblies<span style="font-family: 宋体">属性。</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> VB.NET编译器参数</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: #154857">CompilerParameters myCompilerParameters = <span style="color: blue">new</span> <span style="color: #154857">CompilerParameters</span>();</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 引用的名称列表</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: #154857">StringCollection ReferencedAssemblies</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myCompilerParameters.ReferencedAssemblies;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">ReferencedAssemblies<span style="font-family: 宋体">保存了编辑脚本时使用的程序集，在初始化脚本引擎时，系统已经默认向该列表添加了</span>mscorlib.dll<span style="font-family: 宋体">、</span>System.dll<span style="font-family: 宋体">、</span>System.Data.dll<span style="font-family: 宋体">、</span>System.Xml.dll<span style="font-family: 宋体">、</span>System.Drawing.dll<span style="font-family: 宋体">、</span>System.Windows.Forms.dll<span style="font-family: 宋体">、</span>Microsoft.VisualBasic.dll<span style="font-family: 宋体">等</span>.NET<span style="font-family: 宋体">框架标准程序集，用户可以使用该属性添加第三方程序集来增强脚本引擎的功能。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在前面的说明中，为了实现全局对象和全局函数，需要在</span>VB.NET<span style="font-family: 宋体">编译器的命令上中使用</span>imports<span style="font-family: 宋体">指令导入全局对象和全局函数所在的名称空间，为此笔者定义了一个</span>VBCompilerImports<span style="font-family: 宋体">的属性来保存这些名称空间，定义该属性的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> VB编译器使用的名称空间导入</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: #154857">StringCollection myVBCompilerImports = <span style="color: blue">new</span> <span style="color: #154857">StringCollection</span>();</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> VB编译器使用的名称空间导入</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: #154857">StringCollection VBCompilerImports</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myVBCompilerImports;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在初始化脚本引擎时程序会在</span>VBCompilerImports<span style="font-family: 宋体">列表中添加默认的名称空间</span>Microsoft.VisualBasic<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">准备和执行编译的脚本代码和一些参数后，脚本引擎就来编译脚本代码生成临时程序集了，笔者使用以下的代码来进行编译操作【袁永福原创，转载请注明出处】</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>// 检查程序集缓存区</p>
<p>myAssembly = (System.Reflection.<span style="color: #154857">Assembly)myAssemblies[strRuntimeSource];</span></p>
<p><span style="color: blue">if</span> (myAssembly == <span style="color: blue">null)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; // 设置编译参数</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myCompilerParameters.GenerateExecutable = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myCompilerParameters.GenerateInMemory = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myCompilerParameters.IncludeDebugInformation = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.myVBCompilerImports.Count &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 添加 imports 指令</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Text.<span style="color: #154857">StringBuilder</span> opt = <span style="color: blue">new</span> System.Text.<span style="color: #154857">StringBuilder</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: blue">string</span> import <span style="color: blue">in</span> <span style="color: blue">this</span>.myVBCompilerImports)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (opt.Length &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opt.Append(<span style="color: #a31515">","</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opt.Append(import.Trim());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opt.Insert(0, <span style="color: #a31515">" /imports:"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">for</span> (<span style="color: blue">int</span> iCount = 0; iCount &lt; <span style="color: blue">this</span>.myVBCompilerImports.Count; iCount++)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myCompilerParameters.CompilerOptions = opt.ToString();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }//if</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.bolOutputDebug)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输出调试信息</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Diagnostics.<span style="color: #154857">Debug</span>.WriteLine(<span style="color: #a31515">" Compile VBA.NET script "r"n"</span> + strRuntimeSource);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: blue">string</span> dll <span style="color: blue">in</span> <span style="color: blue">this</span>.myCompilerParameters.ReferencedAssemblies)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Diagnostics.<span style="color: #154857">Debug</span>.WriteLine(<span style="color: #a31515">"Reference:"</span> + dll);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; // 对VB.NET代码进行编译</span></p>
<p><span>&nbsp;&nbsp;&nbsp; Microsoft.VisualBasic.<span style="color: #154857">VBCodeProvider</span> provider = <span style="color: blue">new</span> Microsoft.VisualBasic.<span style="color: #154857">VBCodeProvider</span>();</span></p>
<p><span style="color: blue">#if</span> DOTNET11</p>
<p><span style="color: gray">&nbsp;&nbsp;&nbsp; // 这段代码用于微软.NET1.1</span></p>
<p><span style="color: gray">&nbsp;&nbsp;&nbsp; ICodeCompiler compiler = provider.CreateCompiler();</span></p>
<p><span style="color: gray">&nbsp;&nbsp;&nbsp; CompilerResults result = compiler.CompileAssemblyFromSource(</span></p>
<p><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.myCompilerParameters, </span></p>
<p><span style="color: gray">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strRuntimeSource );</span></p>
<p><span style="color: blue">#else</span></p>
<p><span>&nbsp;&nbsp;&nbsp; // 这段代码用于微软.NET2.0或更高版本</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: #154857">CompilerResults</span> result = provider.CompileAssemblyFromSource(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myCompilerParameters,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strRuntimeSource);</span></p>
<p><span style="color: blue">#endif</span></p>
<p><span>&nbsp;&nbsp;&nbsp; // 获得编译器控制台输出文本</span></p>
<p><span>&nbsp;&nbsp;&nbsp; System.Text.<span style="color: #154857">StringBuilder</span> myOutput = <span style="color: blue">new</span> System.Text.<span style="color: #154857">StringBuilder</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: blue">string</span> line <span style="color: blue">in</span> result.Output)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myOutput.Append(<span style="color: #a31515">""r"n"</span> + line);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.strCompilerOutput = myOutput.ToString();</span></p>
<p><span>&nbsp;&nbsp; &nbsp;<span style="color: blue">if</span> (<span style="color: blue">this</span>.bolOutputDebug)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 输出编译结果</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.strCompilerOutput.Length &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Diagnostics.<span style="color: #154857">Debug</span>.WriteLine(<span style="color: #a31515">"VBAScript Compile result"</span> + strCompilerOutput);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; provider.Dispose();</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (result.Errors.HasErrors == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 若没有发生编译错误则获得编译所得的程序集</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myAssembly = result.CompiledAssembly;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myAssembly != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 将程序集缓存到程序集缓存区中</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myAssemblies[strRuntimeSource] = myAssembly;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这段代码中，首先程序设置编译器的参数，并为</span>VB<span style="font-family: 宋体">编译器添加引用的程序集信息，</span>VB.NET<span style="font-family: 宋体">编译器有个名为</span>imports<span style="font-family: 宋体">的命令行参数用于指定全局名称空间。用法为&#8220;</span>/imports:<span style="font-family: 宋体">名称空间</span>1,<span style="font-family: 宋体">名称空间</span>2<span style="font-family: 宋体">&#8221;，在编译器命令行中使用</span>imports<span style="font-family: 宋体">参数和在代码文本中使用</span>imports<span style="font-family: 宋体">语句是有所不同的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">然后程序创建一个</span>VBCodeProvider<span style="font-family: 宋体">对象开始编译脚本，对于微软</span>.NET<span style="font-family: 宋体">框架</span>1.1<span style="font-family: 宋体">和</span>2.0<span style="font-family: 宋体">其操作过程是有区别的。对微软</span>.NET1.1<span style="font-family: 宋体">还得调用</span>provider<span style="font-family: 宋体">的</span>CreateCompilter<span style="font-family: 宋体">函数创建一个</span>IcodeCompiler<span style="font-family: 宋体">对象，然后调用它的</span>CompileAssemblyFromSource<span style="font-family: 宋体">来编译脚本，而对于微软</span>.NET<span style="font-family: 宋体">框架</span>2.0<span style="font-family: 宋体">则是直接调用</span>provider<span style="font-family: 宋体">的</span>CompileAssemblyFromSource<span style="font-family: 宋体">来编译脚本的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">编译器编译后返回一个</span>CompilerResults<span style="font-family: 宋体">的对象表示编译结果，若发生编译错误程序就输出编译错误信息。若编译成功则程序使用编译结果的</span>CompileAssembly<span style="font-family: 宋体">属性获得编辑脚本代码生成的临时程序集对象了。然后把程序集对象缓存到</span>myAssemblies<span style="font-family: 宋体">列表中。</span></p>
<h3><span style="font-family: 宋体">分析临时程序集</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">调用编译器编译脚本代码后成功的生成临时程序集后，脚本引擎需要分析这个程序集，获得所有的可用的脚本方法，其分析代码为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">if</span> (<span style="color: blue">this.myAssembly != <span style="color: blue">null</span>)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 检索脚本中定义的类型</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: #154857">Type</span> ModuleType = myAssembly.GetType(nsName + <span style="color: #a31515">"."</span> + ModuleName);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (ModuleType != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Reflection.<span style="color: #154857">MethodInfo</span>[] ms = ModuleType.GetMethods(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Reflection.<span style="color: #154857">BindingFlags</span>.Public</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | System.Reflection.<span style="color: #154857">BindingFlags</span>.NonPublic</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | System.Reflection.<span style="color: #154857">BindingFlags</span>.Static);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (System.Reflection.<span style="color: #154857">MethodInfo</span> m <span style="color: blue">in</span> ms)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 遍历类型中所有的静态方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 对每个方法创建一个脚本方法信息对象并添加到脚本方法列表中。</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #154857">ScriptMethodInfo</span> info = <span style="color: blue">new</span> <span style="color: #154857">ScriptMethodInfo</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info.MethodName = m.Name;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info.MethodObject = m;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info.ModuleName = ModuleType.Name;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; info.ReturnType = m.ReturnType;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.myScriptMethods.Add(info);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.bolOutputDebug)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 输出调试信息</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Diagnostics.<span style="color: #154857">Debug</span>.WriteLine(<span style="color: #a31515">"Get vbs method """</span> + m.Name + <span style="color: #a31515">""""</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//foreach</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolResult = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }<span style="color: green">//if</span></span></p>
<p>}<span style="color: green">//if</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这段代码中，程序首先获得脚本模块的类型，在这里类型全名为&#8220;</span>NameSpaceXVBAScriptEngien. mdlXVBAScriptEngine<span style="font-family: 宋体">&#8221;，然后使用反射获得该类型中所有的公开或未公开的静态成员方法对象，对于其中的每一个方法创建一个</span>ScriptMethodInfo<span style="font-family: 宋体">类型的脚本方法信息对象来保存这个方法的一些信息，将这些信息保存到</span>myScriptMethods<span style="font-family: 宋体">列表中供以后调用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者配套定义了</span>ScriptMethodInfo<span style="font-family: 宋体">类型和</span>myScriptMethods<span style="font-family: 宋体">列表，定义它们的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 所有脚本方法的信息列表</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: #154857">ArrayList myScriptMethods = <span style="color: blue">new</span> <span style="color: #154857">ArrayList</span>();</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 脚本方法信息</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">class <span style="color: #154857">ScriptMethodInfo</span></span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 模块名称</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">string</span> ModuleName = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 方法名称</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">string</span> MethodName = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 方法对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> System.Reflection.<span style="color: #154857">MethodInfo</span> MethodObject = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 方法返回值</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> System.<span style="color: #154857">Type</span> ReturnType = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 指向该方法的委托</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> System.<span style="color: #154857">Delegate</span> MethodDelegate = <span style="color: blue">null</span>;</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">使用脚本方法信息列表，脚本引擎调用脚本方法时就不需要使用反射查找脚本方法了，只需要在脚本方法信息列表中快速的查找和调用。</span></p>
<h3><span style="font-family: 宋体">调用脚本</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">脚本引擎前期完成的大量的工作就是为了最后能调用脚本，为此笔者定义了、</span>Execute<span style="font-family: 宋体">函数用于调用指定名称的脚本方法。定义该函数的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行脚本方法</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="MethodName"&gt;<span style="color: green">方法名称&lt;/param&gt;</span></p>
<p>/// &lt;param name="Parameters"&gt;<span style="color: green">参数&lt;/param&gt;</span></p>
<p>/// &lt;param name="ThrowException"&gt;<span style="color: green">若发生错误是否触发异常&lt;/param&gt;</span></p>
<p>/// &lt;returns&gt;<span style="color: green">执行结果&lt;/returns&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">object Execute(<span style="color: blue">string</span> MethodName, <span style="color: blue">object</span>[] Parameters, <span style="color: blue">bool</span> ThrowException)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 检查脚本引擎状态</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (CheckReady() == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (ThrowException)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若发生错误则抛出异常，则检查参数</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (MethodName == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #154857">ArgumentNullException</span>(<span style="color: #a31515">"MethodName"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MethodName = MethodName.Trim();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (MethodName.Length == 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">throw</span> <span style="color: blue">new</span> <span style="color: #154857">ArgumentException</span>(<span style="color: #a31515">"MethodName"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.myScriptMethods.Count &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: #154857">ScriptMethodInfo</span> info <span style="color: blue">in</span> <span style="color: blue">this</span>.myScriptMethods)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 遍历所有的脚本方法信息，不区分大小写的找到指定名称的脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">string</span>.Compare(info.MethodName, MethodName, <span style="color: blue">true</span>) == 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">object</span> result = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (info.MethodDelegate != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: green">// 若有委托则执行委托</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = info.MethodDelegate.DynamicInvoke(Parameters);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若没有委托则直接动态执行方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = info.MethodObject.Invoke(<span style="color: blue">null</span>, Parameters);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 返回脚本方法返回值</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> result;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//foreach</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若发生错误则不抛出异常，安静的退出</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 检查参数</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<span style="color: blue">if</span> (MethodName == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MethodName = MethodName.Trim();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (MethodName.Length == 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.myScriptMethods.Count &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<span style="color: blue">foreach</span> (<span style="color: #154857">ScriptMethodInfo</span> info <span style="color: blue">in</span> <span style="color: blue">this</span>.myScriptMethods)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 遍历所有的脚本方法信息，不区分大小写的找到指定名称的脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">string</span>.Compare(info.MethodName, MethodName, <span style="color: blue">true</span>) == 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">try</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 执行脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">object</span> result = info.MethodObject.Invoke(<span style="color: blue">null</span>, Parameters);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 返回脚本方法返回值</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> result;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">catch</span> (<span style="color: #154857">Exception</span> ext)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若发生错误则输出调试信息</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;System.<span style="color: #154857">Console</span>.WriteLine(<span style="color: #a31515">"VBA:"</span> + MethodName + <span style="color: #a31515">":"</span> + ext.Message);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//foreach</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; }<span style="color: green">//else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p>}<span style="color: green">//public object Execute</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里函数参数为要调用的脚本方法的名称，不区分大小写，调用脚本使用的参数列表，还有控制是否抛出异常的参数。在函数里面，程序遍历</span>myScriptMethods<span style="font-family: 宋体">列表中所有以前找到的脚本方法的信息，查找指定名称的脚本方法，若找到则使用脚本方法的</span>Invoke<span style="font-family: 宋体">函数执行脚本方法，如此陈旭就能调用脚本了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了丰富脚本引擎的编程接口，笔者还定义了</span>HasMethod<span style="font-family: 宋体">函数来判断是否存在指定名称的脚本方法，定义了</span>ExecuteSub<span style="font-family: 宋体">函数来安全的不抛出异常的调用脚本方法。</span></p>
<h2>Window<span style="font-family: 黑体">全局对象</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在很多脚本中存在一个名为&#8220;</span>window<span style="font-family: 宋体">&#8221;的全局对象，该对象大多用于和用户界面互换，并映射到应用系统主窗体。在这里笔者仿造</span>HTML<span style="font-family: 宋体">的</span>javascript<span style="font-family: 宋体">脚本的</span>window<span style="font-family: 宋体">全局对象来构造出自己的</span>window<span style="font-family: 宋体">全局对象。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">参考</span>javascript<span style="font-family: 宋体">中的</span>window<span style="font-family: 宋体">全局对象，对笔者有参考意义的类型成员主要分为映射到屏幕大小或者主窗体的位置大小的属性，还有延时调用和定时调用的方法，还有显示消息框或输入框的方法。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者建立一个</span>XVBAWindowObject<span style="font-family: 宋体">类型作为</span>Window<span style="font-family: 宋体">全局对象的类型。</span></p>
<h3><span style="font-family: 宋体">成员属性</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者首先定义一个</span>UserInteractive<span style="font-family: 宋体">属性，该属性指定应用系统是否能和用户桌面交互。定义该属性的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">protected</span> <span style="color: blue">bool bolUserInteractive = <span style="color: blue">true</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 是否允许和用户交互，也就是是否显示用户界面</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;remarks&gt;</span><span style="color: green">当应用程序为ASP.NET或者Windows Service程序时不能有图形化用户界面，因此需要设置该属性为false.</span><span style="color: gray">&lt;/remarks&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool UserInteractive</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> bolUserInteractive; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { bolUserInteractive = <span style="color: blue">value</span>; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一些应用系统，包括</span>ASP.NET<span style="font-family: 宋体">和</span>Windows Service<span style="font-family: 宋体">，它是不能和用户交互的，不能有图形化用户界面，不能调用</span>MessageBox<span style="font-family: 宋体">函数，不能使用</span>.NET<span style="font-family: 宋体">类库中</span>System.Widnows.Forms<span style="font-family: 宋体">名称空间下的大部分功能，若强行调用则会出现程序错误。这个脚本引擎设计目标是可以运行在任何程序类型中的，包括</span>WinForm<span style="font-family: 宋体">，命令行模式，</span>ASP.NET<span style="font-family: 宋体">和</span>Windows Service<span style="font-family: 宋体">。因此在这里笔者定义了</span>UserInteractive<span style="font-family: 宋体">属性用于关闭</span>window<span style="font-family: 宋体">全局对象的某些和用户互换相关的功能，比如显示消息框，延时调用和定时调用等等，主动关闭这些功能对应用系统的影响是不大的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者还定义了其他的一些属性，其定义的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">protected</span> <span style="color: blue">string strSystemName = <span style="color: #a31515">"应用程序"</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 系统名称</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">string SystemName</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> strSystemName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSystemName = <span style="color: blue">value</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: blue">protected</span> <span style="color: #154857">XVBAEngine myEngine = <span style="color: blue">null</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 脚本引擎对象</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: #154857">XVBAEngine Engine</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myEngine; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: blue">protected</span> System.Windows.Forms.<span style="color: #154857">IWin32Window myParentWindow = <span style="color: blue">null</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 父窗体对象</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> System.Windows.Forms.<span style="color: #154857">IWin32Window ParentWindow</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myParentWindow; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { myParentWindow = <span style="color: blue">value</span>; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 屏幕宽度</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">int ScreenWidth</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> System.Windows.Forms.<span style="color: #154857">Screen</span>.PrimaryScreen.Bounds.Width;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> 0;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 屏幕高度</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">int ScreenHeight</span></p>
<p>{</p>
<p>&nbsp;<span>&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> System.Windows.Forms.<span style="color: #154857">Screen</span>.PrimaryScreen.Bounds.Height;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> 0;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里的</span>ParentWindow<span style="font-family: 宋体">属性表示应用系统的主窗体。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<h3><span style="font-family: 宋体">延时调用和定时调用</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在</span>Window<span style="font-family: 宋体">全局对象中，笔者使用</span>System.Windows.Forms.Timer<span style="font-family: 宋体">对象实现了延时调用和定时调用，由于定时器对象属于用户互换相关的功能，因此延时调用和定时调用受到</span>UserInteractive<span style="font-family: 宋体">属性的影响。笔者使用以下代码来实现延时调用的功能</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">private</span> <span style="color: blue">string strTimeoutMethod = <span style="color: blue">null</span>;</span></p>
<p><span style="color: blue">private</span> System.Windows.Forms.<span style="color: #154857">Timer myTimer;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 设置延时调用</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;param name="MinSecend"&gt;</span><span style="color: green">延时的毫秒数</span><span style="color: gray">&lt;/param&gt;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;param name="MethodName"&gt;</span><span style="color: green">调用的方法名称</span><span style="color: gray">&lt;/param&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">void SetTimeout(<span style="color: blue">int</span> MinSecend, <span style="color: blue">string</span> MethodName)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 若不支持和用户互换则本功能无效</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> ( bolUserInteractive == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myEngine == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp; &nbsp;<span style="color: blue">if</span> (myIntervalTimer != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 取消当前的演示处理</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myIntervalTimer.Stop();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; strTimerIntervalMethod = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myTimer == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若定时器不存在则创建新的定时器对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myTimer = <span style="color: blue">new</span> System.Windows.Forms.<span style="color: #154857">Timer</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myTimer.Tick += <span style="color: blue">new</span> <span style="color: #154857">EventHandler</span>(myTimer_Tick);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 设置定时器</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; myTimer.Interval = MinSecend;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 设置脚本方法名称</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; strTimeoutMethod = MethodName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 启动定时器</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; myTimer.Start();</span></p>
<p>}</p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 清除延时调用</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">void ClearTimeout()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myTimer != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 停止定时器</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myTimer.Stop();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 清空延时调用的脚本方法名称</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; strTimeoutMethod = <span style="color: blue">null</span>;</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 延时调用的定时器事件处理</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;param name="sender"&gt;&lt;/param&gt;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;param name="e"&gt;&lt;/param&gt;</span></p>
<p><span style="color: blue">private</span> <span style="color: blue">void myTimer_Tick(<span style="color: blue">object</span> sender, <span style="color: #154857">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; myTimer.Stop();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myEngine != <span style="color: blue">null</span> &amp;&amp; strTimeoutMethod != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 获得脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> m = strTimeoutMethod.Trim();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strTimeoutMethod = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myEngine.HasMethod(m))</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若脚本引擎中定义了该名称的脚本方法则安全的执行该脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myEngine.ExecuteSub(m);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">SetTimeout<span style="font-family: 宋体">函数用于实现延时调用，它的参数为延时调用的毫秒数和脚本方法名称。在该函数中程序初始化一个名为</span>myTimer<span style="font-family: 宋体">定时器，设置它的</span>Interval<span style="font-family: 宋体">属性为指定的毫秒数，然后启动该定时器。而在</span>myTimer<span style="font-family: 宋体">的定时事件处理中程序停止</span>myTimer<span style="font-family: 宋体">定时器，然后调用脚本引擎的</span>ExecuteSub<span style="font-family: 宋体">函数运行指定名称的无参数脚本方法。使用</span>SetTimeout<span style="font-family: 宋体">只会运行一次脚本方法，在调用</span>SetTimeout<span style="font-family: 宋体">函数准备延时调用后可以调用</span>ClearTimeout<span style="font-family: 宋体">函数来立即取消延时调用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者使用以下代码来实现定时调用的功能</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 定时调用使用的定时器控件</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> System.Windows.Forms.<span style="color: #154857">Timer myIntervalTimer = <span style="color: blue">null</span>;</span></p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 定时调用的脚本方法的名称</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">string strTimerIntervalMethod = <span style="color: blue">null</span>;</span></p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 设置定时运行</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="MinSecend"&gt;<span style="color: green">时间间隔毫秒数&lt;/param&gt;</span></p>
<p>/// &lt;param name="MethodName"&gt;<span style="color: green">方法名称&lt;/param&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">void SetInterval(<span style="color: blue">int</span> MinSecend, <span style="color: blue">string</span> MethodName)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若不能和用户互换则退出处理</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 检查参数</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (MethodName == <span style="color: blue">null</span> || MethodName.Trim().Length == 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: blue">this</span>.myEngine == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myTimer != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">//取消当前的延时调用功能</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myTimer.Stop();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; strTimeoutMethod = <span style="color: blue">null</span>;</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myEngine.HasMethod(MethodName.Trim()) == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; strTimerIntervalMethod = MethodName.Trim();</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myIntervalTimer == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 初始化定时调用的定时器控件</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myIntervalTimer = <span style="color: blue">new</span> System.Windows.Forms.<span style="color: #154857">Timer</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myIntervalTimer.Tick += <span style="color: blue">new</span> <span style="color: #154857">EventHandler</span>(myIntervalTimer_Tick);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; myIntervalTimer.Interval = MinSecend;</span></p>
<p>}</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 清除定时运行</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">void ClearInterval()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myIntervalTimer != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 停止定时调用</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myIntervalTimer.Stop();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; strTimerIntervalMethod = <span style="color: blue">null</span>;</span></p>
<p>}</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 定时调用的定时器事件处理</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="sender"&gt;&lt;/param&gt;</p>
<p>/// &lt;param name="e"&gt;&lt;/param&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">void myIntervalTimer_Tick(<span style="color: blue">object</span> sender, <span style="color: #154857">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myIntervalTimer != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 设置定时调用的脚本方法名称</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strTimerIntervalMethod = strTimerIntervalMethod.Trim();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (strTimerIntervalMethod == <span style="color: blue">null</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || strTimerIntervalMethod.Length == 0</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || myEngine == <span style="color: blue">null</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; || myEngine.HasMethod(strTimerIntervalMethod) == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myIntervalTimer != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若没找到指定名称的脚本方法则停止定时调用</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myIntervalTimer.Stop();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 安全的执行指定名称的脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; myEngine.ExecuteSub(strTimerIntervalMethod);</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">SetInterval<span style="font-family: 宋体">函数用于实现定时调用，它的参数为两次调用之间的时间间隔，以及脚本方法名称。在该函数中程序初始化一个名为</span>myIntervalTimer<span style="font-family: 宋体">的定时器，设置它的</span>Interval<span style="font-family: 宋体">属性为指定的时间间隔，然后启动该定时器。在</span>myIntervalTimer<span style="font-family: 宋体">的定时事件处理中程序调用脚本引擎的</span>ExecuteSub<span style="font-family: 宋体">函数运行指定名称的无参数脚本方法。</span>SetInterval<span style="font-family: 宋体">会无休止的定时调用脚本方法，直到调用</span>ClearInterval<span style="font-family: 宋体">函数终止定时调用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">延时调用和定时调用是相互排斥的过程，启动延时调用会停掉定时调用，而启用定时调用会停掉延时调用。</span></p>
<h3><span style="font-family: 宋体">映射应用程序主窗体</span></h3>
<p style="text-indent: 21pt">Window<span style="font-family: 宋体">全局对象定义了一些属性用于映射应用程序主窗体，笔者定义一个</span>Title<span style="font-family: 宋体">属性应用映射主窗体的文本，其代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 窗体标题</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">string Title</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">Form</span> frm = myParentWindow <span style="color: blue">as</span> System.Windows.Forms.<span style="color: #154857">Form</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (frm == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: #a31515">""</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> frm.Text;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">Form</span> frm = myParentWindow <span style="color: blue">as</span> System.Windows.Forms.<span style="color: #154857">Form</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (frm != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; frm.Text = <span style="color: blue">value</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类似的，笔者定义了</span>Left<span style="font-family: 宋体">，</span>Top<span style="font-family: 宋体">、</span>Width<span style="font-family: 宋体">和</span>Height<span style="font-family: 宋体">属性用于映射主窗体的左边位置、顶边位置，宽度和高度。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">借助于这些</span>Title<span style="font-family: 宋体">、</span>Left<span style="font-family: 宋体">、</span>Top<span style="font-family: 宋体">、</span>Width<span style="font-family: 宋体">和</span>Height<span style="font-family: 宋体">属性，用户就可以在脚本中获得和设置主窗体的一些属性了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这些属性全都是和用户互换相关的功能，因此都受</span>UserInteractive<span style="font-family: 宋体">属性控制。若</span>ASP.NET<span style="font-family: 宋体">程序和</span>Windows Service<span style="font-family: 宋体">程序使用的脚本调用这些属性将不会产生任何效果。对于</span>WinForm<span style="font-family: 宋体">程序，运行脚本前应当将主窗体设置到</span>window<span style="font-family: 宋体">全局对象的</span>ParentWindow<span style="font-family: 宋体">属性上。</span></p>
<h3><span style="font-family: 宋体">显示消息框</span></h3>
<p style="text-indent: 21pt">Window<span style="font-family: 宋体">全局对象还定义了一些函数用于显示一些消息对话框实现用户互换。主要代码为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 将对象转化为用于显示的文本</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objData"&gt;<span style="color: green">要转换的对象&lt;/param&gt;</span></p>
<p>/// &lt;returns&gt;<span style="color: green">显示的文本&lt;/returns&gt;</span></p>
<p><span style="color: blue">private</span> <span style="color: blue">string GetDisplayText(<span style="color: blue">object</span> objData)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (objData == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: #a31515">"[null]"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: #154857">Convert</span>.ToString(objData);</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 显示消息框</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objText"&gt;<span style="color: green">提示信息的文本&lt;/param&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">void Alert(<span style="color: blue">object</span> objText)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">MessageBox</span>.Show(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParentWindow,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetDisplayText(objText),</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SystemName,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">MessageBoxButtons</span>.OK,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">MessageBoxIcon</span>.Information);</span></p>
<p>}</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 显示错误消息框</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objText"&gt;<span style="color: green">提示信息的文本&lt;/param&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">void AlertError(<span style="color: blue">object</span> objText)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">MessageBox</span>.Show(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParentWindow,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetDisplayText(objText),</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SystemName,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;System.Windows.Forms.<span style="color: #154857">MessageBoxButtons</span>.OK,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">MessageBoxIcon</span>.Exclamation);</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 显示一个提示信息框,并返回用户的选择</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objText"&gt;<span style="color: green">提示的文本&lt;/param&gt;</span></p>
<p>/// &lt;returns&gt;<span style="color: green">用户是否确认的信息&lt;/returns&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool ConFirm(<span style="color: blue">object</span> objText)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> (System.Windows.Forms.<span style="color: #154857">MessageBox</span>.Show(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParentWindow,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetDisplayText(objText),</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SystemName,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #154857">MessageBoxButtons</span>.YesNo,</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Windows.Forms.<span style="color: #154857">MessageBoxIcon</span>.Question)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; == System.Windows.Forms.<span style="color: #154857">DialogResult</span>.Yes);</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 显示一个信息输入框共用户输入</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objCaption"&gt;<span style="color: green">输入信息的提示&lt;/param&gt;</span></p>
<p>/// &lt;param name="objDefault"&gt;<span style="color: green">默认值&lt;/param&gt;</span></p>
<p>/// &lt;returns&gt;<span style="color: green">用户输入的信息&lt;/returns&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">string Prompt(<span style="color: blue">object</span> objCaption, <span style="color: blue">object</span> objDefault)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolUserInteractive == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: #154857">dlgInputBox</span>.InputBox(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myParentWindow,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetDisplayText(objCaption),</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SystemName,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GetDisplayText(objDefault));</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 显示一个文本选择对话框</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objCaption"&gt;<span style="color: green">对话框标题&lt;/param&gt;</span></p>
<p>/// &lt;param name="objFilter"&gt;<span style="color: green">文件过滤器&lt;/param&gt;</span></p>
<p>/// &lt;returns&gt;<span style="color: green">用户选择的文件名,若用户取消选择则返回空引用&lt;/returns&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">string BrowseFile(<span style="color: blue">object</span> objCaption, <span style="color: blue">object</span> objFilter)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.Windows.Forms.<span style="color: #154857">OpenFileDialog</span> dlg</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <span style="color: blue">new</span> System.Windows.Forms.<span style="color: #154857">OpenFileDialog</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.CheckFileExists = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (objCaption != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.Title = <span style="color: blue">this</span>.GetDisplayText(objCaption);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (objFilter != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.Filter = GetDisplayText(objFilter);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (dlg.ShowDialog(myParentWindow) == System.Windows.Forms.<span style="color: #154857">DialogResult</span>.OK)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> dlg.FileName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p>}</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 显示一个文件夹选择对话框</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="objCaption"&gt;<span style="color: green">对话框标题&lt;/param&gt;</span></p>
<p>/// &lt;returns&gt;<span style="color: green">用户选择了一个文件夹则返回该路径,否则返回空引用&lt;/returns&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">string BrowseFolder(<span style="color: blue">object</span> objCaption)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.Windows.Forms.<span style="color: #154857">FolderBrowserDialog</span> dlg</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = <span style="color: blue">new</span> System.Windows.Forms.<span style="color: #154857">FolderBrowserDialog</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (objCaption != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.Description = <span style="color: blue">this</span>.GetDisplayText(objCaption);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.RootFolder = System.<span style="color: #154857">Environment</span>.<span style="color: #154857">SpecialFolder</span>.MyComputer;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (dlg.ShowDialog(myParentWindow) == System.Windows.Forms.<span style="color: #154857">DialogResult</span>.OK)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> dlg.SelectedPath;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">调用这些方法，脚本能显示简单的消息框，显示文件选择对话框或文件夹选择对话框以实现和用户的互换。当前这些函数都受到</span>UserInteractive<span style="font-family: 宋体">属性的控制。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里定义了一个</span>Alert<span style="font-family: 宋体">方法用于显示一个简单的消息框，在</span>VB<span style="font-family: 宋体">中可以调用</span>MsgBox<span style="font-family: 宋体">方法来实现相同的功能，但</span>MsgBox<span style="font-family: 宋体">方法是</span>VB<span style="font-family: 宋体">运行库的方法，不受</span>UserInteractive<span style="font-family: 宋体">属性的控制，因此不建议使用，而使用</span>Alert<span style="font-family: 宋体">方法。</span></p>
<h2><span style="font-family: 黑体">测试脚本引擎</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">脚本引擎设计和开发完毕后，袁某就可以编写应用程序来测试使用脚本引擎了。在这里笔者仿造</span>Windows<span style="font-family: 宋体">记事本开发了一个简单的文本编辑器，其用户界面如下。<br /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="432" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/script-demo.png" width="633" border="0" /><br />&nbsp;&nbsp;&nbsp; 在一个标准的</span>C# WinForm<span style="font-family: 宋体">项目中笔者新建一个名为</span>frmMain<span style="font-family: 宋体">的主窗体，上面放置工具条，下面放置一个名为</span>txtEditor<span style="font-family: 宋体">的多行文本框。工具条中放上新增，打开，保存，另存为等按钮并添加事件处理以实现简单文本编辑器的功能。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">主窗体中还定义了诸如</span>Function_New<span style="font-family: 宋体">，</span>Function_Open<span style="font-family: 宋体">，</span>Function_Save<span style="font-family: 宋体">等等函数用于实现对文档的新建、打开文件和保存文件等处理。而工具条上的按钮就是调用这些功能函数。定义这些功能函数的代码如下【袁永福原创，转载请注明出处】</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行新建文档</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">bool Function_New()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (QuerySave())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtEditor.Text = <span style="color: #a31515">""</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtEditor.Modified = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">false</span>;</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行打开文件操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">bool Function_Open()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (QuerySave() == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">false</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (<span style="color: #154857">OpenFileDialog</span> dlg = <span style="color: blue">new</span> <span style="color: #154857">OpenFileDialog</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.Filter = <span style="color: #a31515">"文本文件(*.txt)|*.txt|所有文件|*.*"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.CheckPathExists = <span style="color: blue">true</span>;</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue">if</span> (dlg.ShowDialog(<span style="color: blue">this</span>) == <span style="color: #154857">DialogResult</span>.OK)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IO.<span style="color: #154857">StreamReader</span> reader = <span style="color: blue">new</span> System.IO.<span style="color: #154857">StreamReader</span>(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.FileName, System.Text.<span style="color: #154857">Encoding</span>.GetEncoding(<span style="color: #a31515">"gb2312"</span>));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtEditor.Text = reader.ReadToEnd();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reader.Close();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName = dlg.FileName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; txtEditor.Modified = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">false</span>;</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行保存文档操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;returns&gt;<span style="color: green">操作是否成功&lt;/returns&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool Function_Save()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (strFileName == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (<span style="color: #154857">SaveFileDialog</span> dlg = <span style="color: blue">new</span> <span style="color: #154857">SaveFileDialog</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.Filter = <span style="color: #a31515">"文本文件(*.txt)|*.txt|所有文件|*.*"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.CheckPathExists = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.OverwritePrompt = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (dlg.ShowDialog(<span style="color: blue">this</span>) == <span style="color: #154857">DialogResult</span>.OK)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName = dlg.FileName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; System.IO.<span style="color: #154857">StreamWriter</span> writer = <span style="color: blue">new</span> System.IO.<span style="color: #154857">StreamWriter</span>(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName, <span style="color: blue">false</span>, System.Text.<span style="color: #154857">Encoding</span>.GetEncoding( <span style="color: #a31515">"gb2312"</span> ));</span></p>
<p><span>&nbsp;&nbsp;&nbsp; writer.Write(<span style="color: blue">this</span>.txtEditor.Text);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; writer.Close();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.txtEditor.Modified = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">true</span>;</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行另存为操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">bool Function_SaveAs()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (<span style="color: #154857">SaveFileDialog</span> dlg = <span style="color: blue">new</span> <span style="color: #154857">SaveFileDialog</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.Filter = <span style="color: #a31515">"文本文件(*.txt)|*.txt|所有文件|*.*"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.CheckPathExists = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;dlg.OverwritePrompt = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (dlg.ShowDialog(<span style="color: blue">this</span>) == <span style="color: #154857">DialogResult</span>.OK)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName = dlg.FileName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IO.<span style="color: #154857">StreamWriter</span> writer = <span style="color: blue">new</span> System.IO.<span style="color: #154857">StreamWriter</span>(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strFileName, <span style="color: blue">false</span>, System.Text.<span style="color: #154857">Encoding</span>.GetEncoding(<span style="color: #a31515">"gb2312"</span>));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writer.Write(<span style="color: blue">this</span>.txtEditor.Text);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writer.Close();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.txtEditor.Modified = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">false</span>;</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行全选操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">void Function_SelectAll()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; txtEditor.SelectAll();</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行剪切操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">void Function_Cut()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; txtEditor.Cut();</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行复制操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">void Function_Copy()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; txtEditor.Copy();</span></p>
<p>}</p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行粘帖操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">void Function_Paste()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; txtEditor.Paste();</span></p>
<p>}</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 执行删除操作</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">void Function_Delete()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; txtEditor.SelectedText = <span style="color: #a31515">""</span>;</span></p>
<p>}</p></td></tr></table>
<h3><span style="font-family: 宋体">文档对象</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">笔者袁某在主窗体中定义了一个</span>DocumentClass<span style="font-family: 宋体">的套嵌类型，该类型就是脚本中使用的</span>document<span style="font-family: 宋体">全局对象的类型，其代码为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 脚本中使用的文档对象类型,本对象是对 frmMain 的一个封装</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">public</span> <span style="color: blue">class <span style="color: #154857">DocumentClass</span></span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 初始化对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;param name="frm"&gt;&lt;/param&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">internal</span> DocumentClass(<span style="color: #154857">frmMain</span> frm)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm = frm;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">internal</span> <span style="color: #154857">frmMain</span> myForm = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 设置或返回文档文本内容</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">string</span> Text</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myForm.txtEditor.Text;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myForm.txtEditor.Text = <span style="color: blue">value</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 向文档添加文本内容</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;param name="text"&gt;<span style="color: green">要添加的文本内容</span>&lt;/param&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">void</span> AppendText(<span style="color: blue">string</span> text)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm.txtEditor.AppendText(text);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 设置获得文档中选择的部分</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">string</span> Selection</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myForm.txtEditor.SelectedText; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { myForm.txtEditor.SelectedText = <span style="color: blue">value</span>; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 文档文件名</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">string</span> FileName</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myForm.FileName; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 新建文档</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;<span style="color: green">操作是否成功</span>&lt;/returns&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">bool</span> New()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myForm.Function_New();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 保存文档</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;<span style="color: green">操作是否成功</span>&lt;/returns&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">bool</span> Save()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myForm.Function_Save();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 文档另存为</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;<span style="color: green">操作是否成功</span>&lt;/returns&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">bool</span> SaveAs()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<span style="color: blue">return</span> myForm.Function_SaveAs();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 打开文件</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;<span style="color: green">操作是否成功</span>&lt;/returns&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">bool</span> Open()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myForm.Function_Open();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 剪切</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">void</span> Cut()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm.Function_Cut();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 复制</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">void</span> Copy()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm.Function_Copy();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 粘帖</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">void</span> Paste()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm.Function_Paste();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 删除</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">void</span> Delete()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm.Function_Delete();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; ///<span style="color: green"> 全选</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">void</span> SelectAll()</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myForm.Function_SelectAll();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p>}<span style="color: green">//public class DocumentClass</span></p></td></tr></table>
<p style="text-indent: 21pt">DocumentClass<span style="font-family: 宋体">类型表示记事本当前处理的文档对象。</span></p>
<h3><span style="font-family: 宋体">创建全局对象容器</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">为了在脚本代码中使用</span>document<span style="font-family: 宋体">，</span>window<span style="font-family: 宋体">这样的全局对象，笔者得创建一个类型为</span>GlobalObject<span style="font-family: 宋体">的全局对象容器，定义该类型的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">namespace</span> MyVBAScript.Global</p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span><span style="color: green"> 定义VB.NET脚本使用的全局对象容器类型</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; [Microsoft.VisualBasic.CompilerServices.<span style="color: #2b91af">StandardModuleAttribute</span>()]</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">class</span> <span style="color: #2b91af">GlobalObject</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">internal</span> <span style="color: blue">static</span> <span style="color: #2b91af">XVBAWindowObject</span> myWindow = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span><span style="color: green"> 全局的 window 对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">XVBAWindowObject</span> Window</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myWindow; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">internal</span> <span style="color: blue">static</span> <span style="color: #2b91af">frmMain</span>.<span style="color: #2b91af">DocumentClass</span> myDocument = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span><span style="color: green"> 全局 document 对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">frmMain</span>.<span style="color: #2b91af">DocumentClass</span> Document</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myDocument; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这个脚本全局对象容器类型中，笔者添加了</span>StandardModuleAttribute<span style="font-family: 宋体">特性，并定义了</span>Window<span style="font-family: 宋体">和</span>Document<span style="font-family: 宋体">两个静态属性。未来我们将脚本要操作的</span>window<span style="font-family: 宋体">对象和</span>document<span style="font-family: 宋体">对象设置到这两个静态属性中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">和其他类型不一样，笔者设置该类型的名称空间为</span>MyVBAScript.Global<span style="font-family: 宋体">，这样是为了将全局对象和其他类型区别开来，减少</span>VB.NET<span style="font-family: 宋体">编译器的工作量。</span></p>
<h3><span style="font-family: 宋体">初始化脚本引擎</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在窗体的加载事件中我们初始化脚本引擎，其代码为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p><span style="color: blue">private</span> <span style="color: blue">void frmMain_Load(<span style="color: blue">object</span> sender, <span style="color: #154857">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">//初始化窗体</span></span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 创建脚本引擎</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; myVBAEngine = <span style="color: blue">new</span> <span style="color: #154857">XVBAEngine</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; myVBAEngine.AddReferenceAssemblyByType(<span style="color: blue">this</span>.GetType());</span></p>
<p><span>&nbsp;&nbsp;&nbsp; myVBAEngine.VBCompilerImports.Add(<span style="color: #a31515">"MyVBAScript.Global"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 设置脚本引擎全局对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; MyVBAScript.Global.<span style="color: #154857">GlobalObject</span>.myWindow = <span style="color: blue">new</span> <span style="color: #154857">XVBAWindowObject</span>(<span style="color: blue">this</span>, myVBAEngine, <span style="color: blue">this</span>.Text);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; MyVBAScript.Global.<span style="color: #154857">GlobalObject</span>.myDocument = <span style="color: blue">new</span> <span style="color: #154857">DocumentClass</span>(<span style="color: blue">this</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 加载演示脚本文本</span></span></p>
<p><span>&nbsp;&nbsp; &nbsp;<span style="color: blue">string</span> strDemoVBS = System.IO.<span style="color: #154857">Path</span>.Combine(System.Windows.Forms.<span style="color: #154857">Application</span>.StartupPath, <span style="color: #a31515">"demo.vbs"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (System.IO.<span style="color: #154857">File</span>.Exists(strDemoVBS))</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IO.<span style="color: #154857">StreamReader</span> reader = <span style="color: blue">new</span> System.IO.<span style="color: #154857">StreamReader</span>(strDemoVBS, System.Text.<span style="color: #154857">Encoding</span>.GetEncoding(<span style="color: #a31515">"gb2312"</span>));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> script = reader.ReadToEnd();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reader.Close();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myVBAEngine.ScriptText = script;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myVBAEngine.Compile() == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.txtEditor.Text = <span style="color: #a31515">"编译默认脚本错误:"r"n"</span> + myVBAEngine.CompilerOutput;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 刷新脚本方法列表</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.RefreshScriptMethodList();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p>
<p>&nbsp;</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里程序首先创建了一个名为</span>myVBAEngine<span style="font-family: 宋体">的脚本引擎对象，然后向它的</span>VBCompilerImports<span style="font-family: 宋体">列表添加了全局对象容器类型所在的名称空间</span>MyVBAScript.Global<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">然后程序创建一个文档对象，并填充</span>VB<span style="font-family: 宋体">脚本引擎用的全局对象容器，设置它的</span>Window<span style="font-family: 宋体">和</span>Document<span style="font-family: 宋体">的属性值。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">程序试图加载应用程序所在目录下的</span>demo.vbs<span style="font-family: 宋体">文件中的内容作为默认加载的脚本代码，若成功加载并编译成功则调用</span>RefreshScriptMethodList<span style="font-family: 宋体">来更新用户界面中的可用脚本方法列表，定义</span>RefreshScriptMethodList<span style="font-family: 宋体">函数的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 刷新&#8220;运行脚本&#8221;按钮的下拉菜单项目，显示所有可以执行的脚本方法名称</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">void RefreshScriptMethodList()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 情况脚本方法名称列表</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.btnRunScript.DropDownItems.Clear();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 获得脚本引擎中所有的脚本方法名称</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span>[] names = myVBAEngine.ScriptMethodNames;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (names != <span style="color: blue">null</span> &amp;&amp; names.Length &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 将脚本方法名称添加到&#8220;运行脚本&#8221;的下拉菜单项目中</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: blue">string</span> name <span style="color: blue">in</span> names)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #154857">ToolStripMenuItem</span> item = <span style="color: blue">new</span> <span style="color: #154857">ToolStripMenuItem</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; item.Text = name;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; item.Click += <span style="color: blue">new</span> <span style="color: #154857">EventHandler</span>(ScriptItem_Click);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnRunScript.DropDownItems.Add(item);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myStatusLabel.Text = <span style="color: #a31515">"共加载 "</span> + names.Length + <span style="color: #a31515">" 个脚本方法"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #154857">ToolStripMenuItem</span> item = <span style="color: blue">new</span> <span style="color: #154857">ToolStripMenuItem</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; item.Enabled = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; item.Text = <span style="color: #a31515">"没有加载任何脚本方法"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnRunScript.DropDownItems.Add(item);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myStatusLabel.Text = <span style="color: #a31515">"没有加载任何脚本方法"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个函数的功能是，使用脚本引擎的</span>ScriptMethodNames<span style="font-family: 宋体">属性获得所有可用脚本方法的名称，然后添加到工具条的&#8220;运行脚本&#8221;的下拉菜单中，于是可以到达如下的界面效果。</span></p>
<p align="center"></p>
<h3><span style="font-family: 宋体"><img height="462" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/script-list.png" width="663" border="0" /><br /><br />&nbsp; 编辑脚本</span></h3>
<p><span style="font-family: 宋体">工具条上有一个&#8220;编辑脚本&#8221;的按钮，该按钮是点击事件处理过程为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 编辑脚本按钮事件处理</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="sender"&gt;&lt;/param&gt;</p>
<p>/// &lt;param name="e"&gt;&lt;/param&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">void btnLoadScript_Click(<span style="color: blue">object</span> sender, <span style="color: #154857">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">//显示脚本文本编辑对话框</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (<span style="color: #154857">dlgEditScript</span> dlg = <span style="color: blue">new</span> <span style="color: #154857">dlgEditScript</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">int</span> VersionBack = myVBAEngine.ScriptVersion;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.VBAEngine = <span style="color: blue">this</span>.myVBAEngine;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dlg.ShowDialog(<span style="color: blue">this</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span>( VersionBack != myVBAEngine.ScriptVersion )</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 若脚本引擎内容发生改变则刷新脚本方法下拉菜单项目</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RefreshScriptMethodList();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这段代码中使用了脚本引擎的</span>ScriptVersion<span style="font-family: 宋体">属性，脚本引擎中每进行一次编译时都会更新因此</span>ScriptVersion<span style="font-family: 宋体">属性，因此比较该属性可以判断脚本引擎中当前执行的脚本代码是否修改过。【袁永福原创，转载请注明出处】</span></p>
<p style="text-indent: 21pt">dlgEditScript<span style="font-family: 宋体">是一个脚本代码编辑对话框，其用户界面如下</span></p>
<p align="center"></p>
<h3><span style="font-family: 宋体"><img height="388" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/script-editor.png" width="531" border="0" /><br /><br />&nbsp;&nbsp; 运行脚本</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该文本编辑器中，只能点击工具条的&#8220;运行脚本&#8221;的下拉菜单的某个项目才能运行脚本方法。在属性该下拉菜单的</span>RefreshScriptMethodList<span style="font-family: 宋体">中为每个菜单项目的点击事件绑定了</span>ScriptItem_Click<span style="font-family: 宋体">方法，该</span>ScriptItem_Click<span style="font-family: 宋体">代码为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 运行脚本的下拉菜单项目点击事件处理</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;param name="sender"&gt;&lt;/param&gt;</p>
<p>/// &lt;param name="args"&gt;&lt;/param&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">void ScriptItem_Click(<span style="color: blue">object</span> sender, System.<span style="color: #154857">EventArgs</span> args)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: #154857">ToolStripMenuItem</span> item = (<span style="color: #154857">ToolStripMenuItem</span>)sender;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">try</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 调用脚本执行指定名称的脚本方法</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myVBAEngine.Execute(item.Text, <span style="color: blue">null</span>, <span style="color: blue">true</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">catch</span> (<span style="color: #154857">Exception</span> ext)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<span style="color: #154857">Console</span>.WriteLine(<span style="color: #a31515">"执行脚本 "</span> + item.Text + <span style="color: #a31515">" 错误:"</span> + ext.ToString());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #154857">MessageBox</span>.Show(<span style="color: blue">this</span>, <span style="color: #a31515">"执行脚本 "</span> + item.Text + <span style="color: #a31515">" 错误:"</span> + ext.Message);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">ScriptItem_Click<span style="font-family: 宋体">方法中，首先获得用户点击的菜单项目，然后调用脚本引擎的</span>Execute<span style="font-family: 宋体">方法来执行脚本，菜单项目显示的文本就是脚本方法的名称。</span></p>
<h3><span style="font-family: 宋体">演示用脚本代码说明</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">程序目录下有一个</span>demo.vbs<span style="font-family: 宋体">的文本文件，该文件内容就是演示实用的</span>VBA.NET<span style="font-family: 宋体">脚本。该脚本代码为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 523.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="698">
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> 显示当前使用的脚本代码()</p>
<p><span>&nbsp;&nbsp;&nbsp; document.text = window.engine.ScriptText</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> 插入当前时间()</p>
<p><span>&nbsp;&nbsp;&nbsp; document.Selection = DateTime.Now().ToString(<span style="color: #a31515">"yyyy年MM月dd日HH:mm:ss"</span>)</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> 屏幕状态()</p>
<p><span>&nbsp;&nbsp;&nbsp; window.alert(<span style="color: #a31515">"屏幕大小:"</span> &amp; window.ScreenWidth &amp; <span style="color: #a31515">" * "</span> &amp; window.ScreenHeight&nbsp;_</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp; vbcrlf &amp; <span style="color: #a31515">"窗体位置:"</span> &amp; window.left &amp; <span style="color: #a31515">"&nbsp;"</span> &amp; window.top _</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp; vbcrlf &amp; <span style="color: #a31515">"窗体大小:"</span> &amp; window.Width &amp; <span style="color: #a31515">" * "</span> &amp; window.height )</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> ShowText()</p>
<p><span>&nbsp;&nbsp;&nbsp; window.alert( document.text )</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> MoveWindow()</p>
<p><span>&nbsp;&nbsp;&nbsp; window.left = 100</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> ShowFileName()</p>
<p><span>&nbsp;&nbsp;&nbsp; window.alert( <span style="color: #a31515">"当前文件名为:"</span> &amp; document.FileName )</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">sub</span> AniMoveWindow()</p>
<p><span>&nbsp;&nbsp;&nbsp; window.left = window.left - 10</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span>( window.left &gt; 10 )</span></p>
<p><span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;window.SetTimeout( 500 , <span style="color: #a31515">"AniMoveWindow"</span> )</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">end</span> <span style="color: blue">if</span></span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: blue">dim</span> Rate <span style="color: blue">as <span style="color: blue">double</span></span></p>
<p><span style="color: blue">sub</span> 模拟显示正铉曲线()</p>
<p><span>&nbsp;&nbsp;&nbsp; Rate = Rate + 0.1</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span>( Rate &gt; 50 )</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">exit</span> <span style="color: blue">sub</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">end</span> <span style="color: blue">if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">dim</span> strText <span style="color: blue">as</span> <span style="color: blue">new</span> <span style="color: blue">string</span>( <span style="color: #a31515">" "</span> , 50 + <span style="color: blue">cint</span>( math.sin( Rate ) * 30 ))</span></p>
<p><span>&nbsp;&nbsp;&nbsp; document.AppendText( vbcrlf &amp; strText &amp; <span style="color: #a31515">"######"</span> )</span></p>
<p><span>&nbsp;&nbsp;&nbsp; window.SetTimeout( 100 , <span style="color: #a31515">"模拟显示正铉曲线"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; window.Title = math.sin( Rate )</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: blue">dim</span> strTitle <span style="color: blue">as <span style="color: blue">string</span> = <span style="color: #a31515">"《C#发现之旅》系列课程的VB.NET脚本演示袁永福编写版权所有2008年"</span></span></p>
<p><span style="color: blue">dim</span> TitleCount <span style="color: blue">as <span style="color: blue">integer</span></span></p>
<p><span style="color: blue">sub</span> 在标题栏显示移动字幕()</p>
<p><span>&nbsp;&nbsp;&nbsp; TitleCount = TitleCount + 1 </span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span>( TitleCount &gt; strTitle.Length )</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TitleCount = 0 </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">exit</span> <span style="color: blue">sub</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">end</span> <span style="color: blue">if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; window.Title =&nbsp;strTitle.SubString( strTitle.Length - TitleCount ,&nbsp;&nbsp; TitleCount ) </span></p>
<p><span>&nbsp;&nbsp;&nbsp; window.SetTimeOut( 100 , <span style="color: #a31515">"在标题栏显示移动字幕"</span>)</span></p>
<p><span style="color: blue">end</span> <span style="color: blue">sub</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里说明一下&#8220;模拟显示正铉曲线&#8221;这个脚本方法，首先定义一个</span>Rate<span style="font-family: 宋体">的全局变量作为计数器，每执行一次该计数器加一，若超过</span>50<span style="font-family: 宋体">则退出方法，脚本中使用</span>sin<span style="font-family: 宋体">函数计算出空白字符串的长度生成一个空白字符串，然后使用文档对象的</span>AppendText<span style="font-family: 宋体">方法向当前编辑的文档添加空白字符和结尾字符，这里脚本调用</span>window<span style="font-family: 宋体">对象的</span>SetTimeout<span style="font-family: 宋体">方法来延期调用这个脚本方法自己。于是这个脚本方法每隔</span>100<span style="font-family: 宋体">毫秒执行一次，并使用文本模拟显示正铉曲线，若显示了</span>50<span style="font-family: 宋体">次则停止执行。</span></p>
<p style="text-indent: 21pt">&nbsp;<span style="font-family: 宋体">这样袁某就完成了一个简单的文本编辑器程序，而且该程序能使用</span>VBA.NET<span style="font-family: 宋体">脚本引擎来扩展功能，能方便的进行二次开发。</span></p>
<h2><span style="font-family: 黑体">部署脚本引擎</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在实际开发中，开发人员可以将</span>XVBAEngine<span style="font-family: 宋体">等</span>C#<span style="font-family: 宋体">代码拷贝到应用程序中即可添加脚本功能，也可以将修改本</span>C#<span style="font-family: 宋体">工程的属性使其单独编译成一个</span>DLL<span style="font-family: 宋体">然后供其他</span>.NET<span style="font-family: 宋体">程序使用。部署起来非常方便。</span></p>
<h2><span style="font-family: 黑体">小结</span></h2>
<p><span style="font-family: 宋体">在本次课程中，笔者使用动态编译技术实现了</span>VBA.NET<span style="font-family: 宋体">脚本引擎，目前很多商业软件，比如</span>OFFICE<span style="font-family: 宋体">，</span>VS.NET<span style="font-family: 宋体">等等都具有二次开发用的</span>VBA<span style="font-family: 宋体">脚本技术，使用本课程介绍的知识我们也可以为应用系统配置功能强大的脚本引擎，这能比较大的提高应用系统的灵活性。脚本引擎技术是一个非常实用的软件开发技术，值得推广。</span></p><img src="http://www.cnblogs.com/xdesigner/aggbug/1531742.html?type=1" width="1" height="1" alt=""/><p>评论: 2　<a href="http://www.cnblogs.com/xdesigner/archive/2009/07/27/1531742.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/07/27/1531742.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>搜狐首页出现一个硕大的错别字</title><link>http://www.cnblogs.com/xdesigner/archive/2009/06/30/1514191.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Tue, 30 Jun 2009 10:05:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/06/30/1514191.html</guid><description><![CDATA[<p>阅读: 429 评论: 0 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-06-30 18:05 <a href="http://www.cnblogs.com/xdesigner/archive/2009/06/30/1514191.html" target="_blank">原文链接</a></p><p><img height="653" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/sohu.PNG" width="725" border="0" /></p><img src="http://www.cnblogs.com/xdesigner/aggbug/1514191.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/xdesigner/archive/2009/06/30/1514191.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/06/30/1514191.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>出口货物退（免）税申报系统天博报表软件应用案例</title><link>http://www.cnblogs.com/xdesigner/archive/2009/05/04/1448795.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Mon, 04 May 2009 07:57:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/05/04/1448795.html</guid><description><![CDATA[<p>阅读: 792 评论: 0 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-05-04 15:57 <a href="http://www.cnblogs.com/xdesigner/archive/2009/05/04/1448795.html" target="_blank">原文链接</a></p><h2 align="center">出口货物退（免）税申报系统天博报表软件应用案例</h2>
<p align="center"><span style="font-family: 宋体">南京擎天科技有限公司</span> 2009-2-17</p>
<p align="center">&nbsp;</p>
<p>本文件的Word版本<a href="http://files.cnblogs.com/xdesigner/出口货物退免税申报系统天博报表软件应用案例.doc" target="_blank">http://files.cnblogs.com/xdesigner/出口货物退免税申报系统天博报表软件应用案例.doc</a></p>
&nbsp;</span>前言
<h3></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在擎天天博报表软件产品组的支持下，我们在《</span><span style="color: black; font-family: 宋体">出口货物退（免）税申报系统</span><span style="font-family: 宋体">》中成功的使用了天博报表软件产品，实现了</span>C/S<span style="font-family: 宋体">程序在复杂运行环境下的显示和打印报表的功能。这个项目突出展示了天博报表软件对</span>C/S<span style="font-family: 宋体">系统开发的支持。</span></p>
<h3>项目介绍</h3>
<p style="text-indent: 21pt" align="left"><span style="color: black; font-family: 宋体">《出口货物退（免）税申报系统》是出口企业向海关申报出口退免税信息的应用系统。企业用户在该系统中输入正确的申报信息，</span><span style="font-family: 宋体">这些信息最终都会汇集到海关的金税系统中，本系统需要实现</span>47<span style="font-family: 宋体">个报表功能。该系统采用基于微软</span>.NET2.0<span style="font-family: 宋体">的</span>C/S<span style="font-family: 宋体">架构，客户端软件将安装在数万家企业中，因此软件安装和运行环境复杂，还存在大面积的软件自动更新和升级的问题，这对软件的部署和维护方面提出了很高的要求。</span></p>
<p style="text-indent: 21pt" align="left"><img height="300" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/taxclient-login.jpg" width="500" border="0" />&nbsp;</p>
<p align="center"></p>
<h3>系统架构</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">《</span><span style="color: black; font-family: 宋体">出口货物退（免）税申报系统</span><span style="font-family: 宋体">》针对出口企业的规模等情况，分为单机版和网络版供用户挑选使用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">单机版软件运行在一台独立的电脑上，使用轻量级的可在单机上使用的关系型数据库，单机版软件使用</span>ADO.NET<span style="font-family: 宋体">直接连接数据库，但天博报表软件不直接连接数据库，而是使用单机版程序提供的数据表对象（</span>.NET<span style="font-family: 宋体">开发中使用的</span>System.Data.DataTable<span style="font-family: 宋体">类型）来作为数据源生成报表。单机版的系统架构如下图所示</span>&nbsp;<span style="font-family: 宋体"><img height="328" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/taxclient-local.gif" width="553" border="0" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">《</span><span style="color: black; font-family: 宋体">出口货物退（免）税申报系统</span><span style="font-family: 宋体">》网络版运行在企业局域网内，此时系统分为客户端和服务器端，服务器端为一个</span>Windows Service<span style="font-family: 宋体">程序，使用</span>ADO.NET<span style="font-family: 宋体">连接</span>MS SQL Server<span style="font-family: 宋体">数据库；但客户端不连接数据库，而是采用</span>.NET Remoting<span style="font-family: 宋体">技术向服务器端发出查询和更新数据库的请求，由服务器端代为访问数据库。客户端将查询获得的数据组织成数据表对象（</span>.NET<span style="font-family: 宋体">编程中的</span>System.Data.DataTable<span style="font-family: 宋体">类型）然后提供给天博报表软件，天博报表软件将根据数据表对象来生成报表。网络版的系统架构如下图所示</span></p>
<p align="center"></p>
<h3><img height="306" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/taxclient-net.gif" width="554" border="0" /></h3>
<h3>数据源处理</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在《</span><span style="color: black; font-family: 宋体">出口货物退（免）税申报系统</span><span style="font-family: 宋体">》的单机版和网络版中，天博报表软件都不连接数据库，而是使用应用系统生成的数据表对象（</span>.NET<span style="font-family: 宋体">中的</span>System.Data.DataTable<span style="font-family: 宋体">类型）来作为数据源生成报表，这就能达到报表模板文件的重复使用的功能，减少软件的开发和维护工作量。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">当天博报表使用数据表对象作为数据源时，报表引擎能根据报表数据源的设计，将数据表中的数据分解导入到报表数据源中，从而生成报表文档。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在少数报表中，天博报表使用</span>DataGridView<span style="font-family: 宋体">控件（</span>System.Windows.Forms.DataGriidView<span style="font-family: 宋体">类型）作为数据源，天博报表能解析</span>DataGirdView<span style="font-family: 宋体">控件的内容，并让报表文档中的一个表格模拟这个</span>DataGridView<span style="font-family: 宋体">控件进行显示，比如这个控件的行数、列数、行高、列宽，其中每个单元格的文本内容，字体颜色等各种显示样式，报表文档都能比较精确的模拟显示出来，甚至当用户手动改变了</span>DataGridView<span style="font-family: 宋体">控件的列宽和行高，报表引擎都能重新生成报表文档来模拟显示控件的当前显示样式。</span></p>
<h3>套打</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在本系统中，存在不少发票套打的功能需求，我们使用了天博报表软件来实现套打功能，下图为天博报表设计环境中一种使用套打的专用发票的报表模板设计界面。</span><span style="font-family: 宋体"><img height="819" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/taxclient-report.jpg" width="736" border="0" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在该发票中红线方框区域为一个很特殊的区域，在进行打印预览时需要显示竖的栏目线，但在实际打印时，由于印刷的发票中已经印有竖线，此时不能打印竖线，为此我们使用了天博报表软件的</span>VB<span style="font-family: 宋体">脚本功能。我们在红色方框区域的单元格中设置了如下的脚本代码</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tr>
            <td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 577.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="770">
            <p align="left"><span style="font-size: 11pt; color: blue">if Document</span><span style="font-size: 11pt; color: black">.State = DocumentState.Painting </span><span style="font-size: 11pt; color: blue">then </span></p>
            <p align="left"><span style="font-size: 11pt; color: blue">&nbsp;&nbsp;&nbsp; this</span><span style="font-size: 11pt; color: black">.LeftBorder = </span><span style="font-size: 11pt; color: blue">true</span></p>
            <p align="left"><span style="font-size: 11pt; color: blue">&nbsp;&nbsp;&nbsp; this</span><span style="font-size: 11pt; color: black">.RightBorder = </span><span style="font-size: 11pt; color: blue">true</span></p>
            <p align="left"><span style="font-size: 11pt; color: blue">else </span></p>
            <p align="left"><span style="font-size: 11pt; color: blue">&nbsp;&nbsp;&nbsp; this</span><span style="font-size: 11pt; color: black">.LeftBorder = </span><span style="font-size: 11pt; color: blue">false</span></p>
            <p align="left"><span style="font-size: 11pt; color: blue">&nbsp;&nbsp;&nbsp; this</span><span style="font-size: 11pt; color: black">.RightBorder = </span><span style="font-size: 11pt; color: blue">false</span></p>
            <p><span style="font-size: 11pt; color: blue">end if</span></p>
            </td>
        </tr>
    </table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里的&#8220;</span>Document.State<span style="font-family: 宋体">&#8221;表示报表文档当前的状态，这段脚本代码的功能是，若报表处于打印预览状态，则显示单元格的左边框线和右边框线，若处于其他状态在不显示左边框线和右边框线。</span></p>
<h3>部署和维护</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">《</span><span style="color: black; font-family: 宋体">出口货物退（免）税申报系统</span><span style="font-family: 宋体">》是一个基于</span>WinForm.NET2.0<span style="font-family: 宋体">的桌面应用，却部署和运行在数万家企业的信息系统中，这些企业分布比较散，软件运行环境非常复杂，而且本系统有软件和数据库的自动更新和升级的需求，因此对本系统的部署和维护方面提出了很高的要求。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">天博报表引擎的部署和维护是很方便。天博报表引擎全部内容都包含在一个名为</span>SkyReports20.DLL<span style="font-family: 宋体">的</span>.NET<span style="font-family: 宋体">程序集文件中，不依赖任何其他第三方的软件组件，应用系统更新程序只需要获得文件</span>SkyReports20.dll<span style="font-family: 宋体">的版本号就可判断是否需要更新报表模块，然后从更新源处下载最新的</span>SkyReports20.dll<span style="font-family: 宋体">文件并覆盖掉旧文件即可完成报表软件模块的更新。天博报表软件使用的报表模板文件都是一个个独立的扩展名为</span>XRP<span style="font-family: 宋体">的文件，这些文件文件一般只有几十</span>K<span style="font-family: 宋体">，更新程序只要检查报表模板文件的</span>MD5<span style="font-family: 宋体">编码即可判断是否需要更新。</span></p>
<h3>案例小结</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在开发《退（免）税申报系统》中，我们在使用天博报表软件的实践过程中，觉得该报表软件具有以下几个特点。</span></p>
<ol>
    <li>编程接口比较简单方便，天博报表提供的WinForm.NET编程接口比较简单，使用方便。天博报表提供了报表预览WinForm控件，在使用VS.NET开发过程中，将其从工具箱拖拽到窗体界面上即可使用，相关的程序代码量少，结构简单。</li>
    <li>部署和维护比较方法，该应用系统是一个WinForm程序，但运行在数万家企业内部，软件的运行环境非常复杂，存在大面积的软件自动更新和升级的问题。而天博报表引擎功能是强大的，文件却只有一个，更新和部署非常方便。这比较大的减少了我们开发软件更新模块的工作量。</li>
    <li>强大的脚本功能，天博报表支持VB.NET语法的脚本功能，我们可以在数据源中、单元格等很多地方设置脚本，脚本可以调整报表文档的很多设置，使用脚本能大量减少应用系统编码工作量，可以在线的修改报表脚本，部署和维护非常方便。 </li>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src="http://www.cnblogs.com/xdesigner/aggbug/1448795.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/xdesigner/archive/2009/05/04/1448795.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/05/04/1448795.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>C#发现之旅 --- C#开发Windows Service程序</title><link>http://www.cnblogs.com/xdesigner/archive/2009/04/06/1430301.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Mon, 06 Apr 2009 07:56:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/04/06/1430301.html</guid><description><![CDATA[<p>阅读: 4386 评论: 16 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-04-06 15:56 <a href="http://www.cnblogs.com/xdesigner/archive/2009/04/06/1430301.html" target="_blank">原文链接</a></p><h1><span style="font-family: 宋体">C#发现之旅 </span>C#<span style="font-family: 宋体">开发Windows Service</span><span style="font-family: 宋体">程序</span></h1>
<h1><span style="font-family: 宋体"></span>&nbsp;</h1>
<h2><span style="font-family: 黑体">本课程介绍</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">本课程说明了</span>Windows Service<span style="font-family: 宋体">程序的概念，并演示如何使用</span>C#<span style="font-family: 宋体">开发一个简单的</span>Windows Service<span style="font-family: 宋体">程序。</span>C#<span style="font-family: 宋体">工程名为</span>MyWindowsService<span style="font-family: 宋体">，编译生成的文件是</span>MyWindowsService.exe<span style="font-family: 宋体">。本课程的演示代码下载地址为<a href="http://files.cnblogs.com/xdesigner/MyWindowsService.zip">http://files.cnblogs.com/xdesigner/MyWindowsService.zip</a>。</span></p>
<h2>Windows Service<span style="font-family: 黑体">概念介绍</span></h2>
<p style="text-indent: 21pt">Windows Service<span style="font-family: 宋体">，也称</span>Windows<span style="font-family: 宋体">服务，是</span>32<span style="font-family: 宋体">位</span>Windows<span style="font-family: 宋体">操作系统中一种长期运行的后台程序。它们长期后台运行，没有用户界面，默默无闻，但它们却是支持</span>Windows<span style="font-family: 宋体">正常运行的幕后英雄，却永无出头之日。</span></p>
<p style="text-indent: 21pt">Windows<span style="font-family: 宋体">服务程序为其他系统模块提供了非常重要的服务，而且各个</span>Windows<span style="font-family: 宋体">服务分工明确，比如</span>IISAdmin<span style="font-family: 宋体">服务提供</span>WEB<span style="font-family: 宋体">内容的发布功能，若</span>IISAdmin<span style="font-family: 宋体">服务不启动，则静态</span>HTML<span style="font-family: 宋体">页面、</span>ASP<span style="font-family: 宋体">、</span>ASP.NET<span style="font-family: 宋体">或者</span>WebService<span style="font-family: 宋体">等等统统不行；有个名为&#8220;</span>Print Spooler<span style="font-family: 宋体">&#8221;的服务用于提供打印支持，若该服务不启动，则任何软件都不能进行打印，比如</span>Word<span style="font-family: 宋体">，记事本或者报表软件等等。</span></p>
<p style="text-indent: 21pt">Windows<span style="font-family: 宋体">启动后在没有用户登录时就会启动</span>Windows<span style="font-family: 宋体">服务。</span>Windows NT<span style="font-family: 宋体">和</span>Windows2000<span style="font-family: 宋体">，以及更新的版本操作系统能运行</span>Windows<span style="font-family: 宋体">服务，但</span>Windows98<span style="font-family: 宋体">及其前期版本是不能运行服务的。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们打开</span>Windows<span style="font-family: 宋体">资源管理器，在左边的树状列表中选中&#8220;桌面</span>-<span style="font-family: 宋体">控制面板</span>-<span style="font-family: 宋体">管理工具&#8221;。</span> </p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/controlpanle.png" border="0" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在右边的列表中打开&#8220;服务&#8221;项目即可打开</span>Windows<span style="font-family: 宋体">服务管理器。</span></p>
<p style="text-indent: 21pt">&nbsp;<span style="font-family: 宋体"><img height="478" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/servicecontrol.png" width="663" border="0" />在这些服务中，有我们最熟悉的</span>IIS Admin<span style="font-family: 宋体">和</span>World Wide Web Publishing<span style="font-family: 宋体">服务了。我们双击一个服务项目即可打开服务属性对话框。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="450" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/iis-property.png" width="410" border="0" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt">Windows<span style="font-family: 宋体">服务有一个服务名称属性，该属性是服务的惟一的不可重复的名称，我们可以在命令行中使用命令&#8220;</span>net start <span style="font-family: 宋体">服务名称&#8221;来启动服务，使用&#8220;</span>net stop <span style="font-family: 宋体">服务名称&#8221;来停止服务。</span></p>
<p style="text-indent: 21pt">Windows<span style="font-family: 宋体">服务的启动类型有自动，手动和已禁用。当启动类型为自动时，</span>Windows<span style="font-family: 宋体">启动后不等用户登录就自动启动服务，当启动类型为手动时，需要某个操作员登录后点击这里的&#8220;启动&#8221;按钮来启动服务，而当启动类型为已禁用时，</span>Windows<span style="font-family: 宋体">服务不能启动。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该页面中的&#8220;启动&#8221;按钮用于启动尚未启动的</span>Windows<span style="font-family: 宋体">服务，运行提供服务的进程；&#8220;停止&#8221;按钮用于停止已经启动的服务，杀死服务进程；而&#8220;暂停&#8221;按钮用于通知服务进程暂时停止提供服务，但服务进程依然存在；而&#8220;恢复&#8221;按钮用于通知处于暂停模式的服务进程重新提供服务。</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">我们可以查看服务属性对话框的&#8220;登录&#8221;页面。</span></p>
<p><span style="font-family: 宋体"><img height="450" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/iis-login.png" width="410" border="0" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">可以指定服务使用本地系统帐户登录，也可另外指定其他的用户，这里有一个允许服务和桌面交互的选项，若选中此选项，则</span>Windows<span style="font-family: 宋体">服务可以显示图形化用户界面，比如显示自己的窗体，显示消息框等等。不过不建议使用该选项，而且</span>Windows<span style="font-family: 宋体">服务运行时不要显示图形化用户界面。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们切换到&#8220;依存关系&#8221;页面，可以看到本服务和其他服务的依存关系。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="450" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/iis-depend.png" width="410" border="0" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">各个</span>Windows<span style="font-family: 宋体">服务之间可能存在依赖关系，比如</span>IISADMIN<span style="font-family: 宋体">服务就依赖另外一个名为</span>RPC<span style="font-family: 宋体">的</span>Windows<span style="font-family: 宋体">服务，当启动一个</span>Windows<span style="font-family: 宋体">服务时，系统会启动该服务所依赖的其他</span>Windows<span style="font-family: 宋体">服务。例如我们设置</span>IISADMIN<span style="font-family: 宋体">服务为自动启动，而</span>RPC<span style="font-family: 宋体">服务为手动启动，则</span>Windows<span style="font-family: 宋体">启动后会试图自动启动</span>IISADMIN<span style="font-family: 宋体">服务，结果会首先启动</span>RPC<span style="font-family: 宋体">服务，即使</span>RPC<span style="font-family: 宋体">服务不是自动启动。若</span>RPC<span style="font-family: 宋体">服务为禁止，无论如何也不能启动，则</span>IISADMIN<span style="font-family: 宋体">服务就无法自动启动了。</span></p>
<h2>C#<span style="font-family: 黑体">编写Windows</span><span style="font-family: 黑体">服务的基本过程</span></h2>
<p style="text-indent: 18pt"><span style="font-family: 宋体">编写</span>Windows<span style="font-family: 宋体">服务是一种比较高级的编程技术，内部使用了很多</span>Windows<span style="font-family: 宋体">操作系统的核心功能，但微软</span>.NET<span style="font-family: 宋体">框架已经很好的封装了这些技术细节，使得我们可以很方便的使用</span>C#<span style="font-family: 宋体">编写自己的</span>Windows<span style="font-family: 宋体">服务，其基本过程一般为</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 宋体">创建</span>C#</strong><strong><span style="font-family: 宋体">工程</span></strong><span style="font-family: 宋体">。创建一个</span>EXE<span style="font-family: 宋体">工程，可以是</span>WinForm<span style="font-family: 宋体">或者命令行格式的。添加对</span>System.ServiceProcess.dll<span style="font-family: 宋体">和</span>System.Configuration.Install.dll<span style="font-family: 宋体">的引用。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 宋体">创建服务类</span></strong><span style="font-family: 宋体">。新增一个类，该类型继承</span>System.ServiceProcess.ServiceBase<span style="font-family: 宋体">类型，在构造函数中设置</span>ServiceName<span style="font-family: 宋体">属性来指明该服务的名称。然后重载它的</span>OnStart<span style="font-family: 宋体">方法来响应启动服务的事件，重载</span>OnStop<span style="font-family: 宋体">方法来响应停止服务的事件，重载</span>OnPause<span style="font-family: 宋体">方法来响应暂停服务的事件，重载</span>OnContinue<span style="font-family: 宋体">方法来响应恢复提供服务的事件。在重载这些方法时必须要立即返回，其中不能出现长时间的操作，若处理时间过长则</span>Windows<span style="font-family: 宋体">服务管理器会觉得该</span>Windows<span style="font-family: 宋体">服务停止响应而报错。为此我们可以使用一个线程来进行实际的工作，而</span>OnStart<span style="font-family: 宋体">方法创建线程，</span>OnStop<span style="font-family: 宋体">方法关闭线程，</span>OnPause<span style="font-family: 宋体">方法挂起线程，而</span>OnContinue<span style="font-family: 宋体">方法来恢复运行线程。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 宋体">启动服务</span></strong><span style="font-family: 宋体">。在</span>main<span style="font-family: 宋体">函数中调用&#8220;</span><span style="color: blue">System.ServiceProcess.ServiceBase.Run( </span><span style="color: blue; font-family: 宋体">自定义服务类的实例</span><span style="color: blue"> )</span><span style="font-family: 宋体">&#8221;来运行服务。比如&#8220;</span><span style="color: blue">System.ServiceProcess.ServiceBase.Run( new MyService() )</span><span style="font-family: 宋体">&#8221;，这里的</span>MyService<span style="font-family: 宋体">就是继承自</span>ServiceBase<span style="font-family: 宋体">。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">4.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 宋体">安装服务</span></strong><span style="font-family: 宋体">。新增一个类，该类型继承自</span><span style="color: blue">System.Configuration.Install.Installer</span><span style="font-family: 宋体">类型，该类型用于配合微软</span>.NET<span style="font-family: 宋体">框架自带的安装命令行工具</span>InstallUtil.exe<span style="font-family: 宋体">的。我们为该类型附加</span><span style="color: blue">System.ComponentModel.RunInstallerAttribute</span><span style="font-family: 宋体">特性，并在它的构造函数中使用</span><span style="color: blue">System.ServiceProcess.ServiceInstaller</span><span style="font-family: 宋体">对象和</span><span style="color: blue">System.ServiceProcess.ServiceProcessInstaller</span><span style="font-family: 宋体">对象向系统提供该服务的安装信息。程序编译后我们可以使用命令行&#8220;</span><span style="color: blue">InstallUtil.exe&nbsp;&nbsp; EXE</span><span style="color: blue; font-family: 宋体">文件名</span><span style="font-family: 宋体">&#8221;向</span>Windows<span style="font-family: 宋体">服务管理器注册服务，可以使用命令行&#8220;</span><span style="color: blue">InstallUtil.exe&nbsp;/u&nbsp;EXE</span><span style="color: blue; font-family: 宋体">文件名</span><span style="font-family: 宋体">&#8221;从</span>Windows<span style="font-family: 宋体">服务管理器中注销服务。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">5.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-family: 宋体">编写服务客户端</span></strong><span style="font-family: 宋体">。这是一个根据实际情况而可选的过程，由于</span>Windows<span style="font-family: 宋体">服务是没有用户界面的，因此我们可以编写一个具有用户界面的程序来显示和控制</span>Windows<span style="font-family: 宋体">服务提供的数据，并进行一些系统设置等操作。比如对于</span>MS SQL Server<span style="font-family: 宋体">，数据库引擎是以服务的形式存在，而</span>SQL Server<span style="font-family: 宋体">企业管理器就是一个客户端软件。</span></p>
<h2><span style="font-family: 黑体">软件功能需求</span></h2>
<p style="text-indent: 18pt"><span style="font-family: 宋体">现在我们要求使用</span>C#<span style="font-family: 宋体">和</span>VS.NET2005<span style="font-family: 宋体">开发一个软件，该软件功能为</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">1.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">该软件能监视指定目录下的文件和子目录的新增，修改，删除和重命名操作，并将操作日志记录到一个数据库中。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">2.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">该软件以</span>Windows<span style="font-family: 宋体">服务的形式运行，能监视不同的用户帐户的操作记录。</span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt">3.<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">有一个客户端软件能控制服务，并能查看服务的保存的监视记录。其用户界面为</span><br /><br /><span style="font-family: 宋体"><img height="437" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/service-client-ui.png" width="585" border="0" /></span></p>
<p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt"><span style="font-family: 宋体">客户端软件还能设置服务监视的目录，系统设置对话框为</span></p>
<h2><span style="font-family: 黑体"><img height="340" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/service-config.png" width="485" border="0" /></span></h2>
<h2><span style="font-family: 黑体">软件设计</span></h2>
<h3><span style="font-family: 宋体">命令行参数设计</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一般而言，我们将服务和客户端分成两个</span>C#<span style="font-family: 宋体">工程开发，但这里为了方便我们只在一个工程中实现服务器和客户端软件的开发。</span>Windows<span style="font-family: 宋体">服务是不能显示图形化用户界面的，但并不是说</span>Windows<span style="font-family: 宋体">服务的软件中不能包含显示图形化用户界面的软件模块。我们完全可以编写一个</span>EXE<span style="font-family: 宋体">，其中包含服务器和客户端两个相互独立的软件模块。直接执行</span>EXE<span style="font-family: 宋体">将以服务模式运行，若带有命令行参数将以客户端模式运行。为此我们设计了如下的命令行参数</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 72.3pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="96">
<p><span style="font-family: 宋体">命令行参数</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: #ece9d8; width: 365.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="487">
<p><span style="font-family: 宋体">功能</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 72.3pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="96">
<p><span style="font-family: 宋体">无任何参数</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 365.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="487">
<p><span style="font-family: 宋体">以服务模式运行，调用</span>ServiceBase.Run<span style="font-family: 宋体">函数来运行服务。</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 72.3pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="96">
<p>/install</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 365.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="487">
<p><span style="font-family: 宋体">调用</span>InstallUtil.exe<span style="font-family: 宋体">安装服务，将</span>EXE<span style="font-family: 宋体">自己注册到</span>Windows<span style="font-family: 宋体">服务管理器中。</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 72.3pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="96">
<p>/uninstall</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 365.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="487">
<p><span style="font-family: 宋体">调用</span>InstallUtil.exe<span style="font-family: 宋体">卸载服务。</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 72.3pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="96">
<p>/client</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 365.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="487">
<p><span style="font-family: 宋体">以客户端模式运行，显示图形用户界面。</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 72.3pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="96">
<p>/debug</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 365.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="487">
<p><span style="font-family: 宋体">以调试模式下运行，方便</span>VS.NET<span style="font-family: 宋体">对服务的操作过程提供调试。</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">使用</span>VS.NET<span style="font-family: 宋体">调试服务是一个比较麻烦的事，首先我们得安装并运行服务，然后使用</span>VS.NET<span style="font-family: 宋体">的菜单项目&#8220;工具</span>-<span style="font-family: 宋体">附加到进程&#8221;的操作来附加到服务程序，然后设置断点进行调试，其中</span>OnStart<span style="font-family: 宋体">函数是没有办法设置断点调试的。为此我们专门添加一个&#8220;</span>/debug<span style="font-family: 宋体">&#8221;命令行参数使得程序不进入服务模式，而是直接运行提供服务内容的功能性代码，然后主线程休眠，但功能性代码还在运行，可以调试。这样我们在</span>VS.NET<span style="font-family: 宋体">中设置断点后可以直接运行进行调试了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里我们设计的</span>C#<span style="font-family: 宋体">工程名称为</span>MyWindowsService<span style="font-family: 宋体">，编译生成的文件为</span>MyWindowsService.exe<span style="font-family: 宋体">。</span></p>
<h3><span style="font-family: 宋体">数据库设计</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在本软件中，数据将保存到应用程序目录下的一个名为</span>FileSystemWatcher.mdb<span style="font-family: 宋体">的</span>Access2000<span style="font-family: 宋体">格式的数据库。数据库中的表结构为</span></p>
<p style="text-indent: 21pt"><strong><span style="font-family: 宋体">文件系统操作日志表</span> FileSystemLog</strong><span style="font-family: 宋体">，字段有</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="229">
<p><span style="font-family: 宋体">字段名</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="90">
<p><span style="font-family: 宋体">类型</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="367">
<p><span style="font-family: 宋体">说明</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="229">
<p>RecordID</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="90">
<p><span style="font-family: 宋体">文本</span>(50)</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="367">
<p><span style="font-family: 宋体">记录编号</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="229">
<p>WatchTime</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="90">
<p><span style="font-family: 宋体">文本</span>(20)</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="367">
<p><span style="font-family: 宋体">记录时间，为</span>yyyy-MM-dd HH:mm:ss<span style="font-family: 宋体">格式</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="229">
<p>ObjectName</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="90">
<p><span style="font-family: 宋体">文本</span>(250)</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="367">
<p><span style="font-family: 宋体">对象名称</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="229">
<p>EventStyle</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="90">
<p><span style="font-family: 宋体">文本</span>(50)</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="367">
<p><span style="font-family: 宋体">事件类型</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该数据表中保存的数据范例为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e0e0e0; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="172">
<p>RecordID</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e0e0e0; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="172">
<p>WatchTime</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e0e0e0; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="172">
<p>ObjectName</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e0e0e0; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="172">
<p>EventStyle</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>0d4e0d9a-6826-415b-bd47-c86fbb1449b0</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 15:31:27</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"aaaaaa.txt</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Renamed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>22c1df6d-4f94-488c-a705-e8024d875213</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 20:37:03</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>d:"aa.png</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Renamed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>27632fe8-6cbf-4a41-95ad-6ab2e8222192</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 20:40:56</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"a.pdf</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Created</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>48403266-0150-44c8-8efa-169f7a68bcb4</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-03 11:02:04</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"zzzzzz.bmp</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Renamed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>6c3b603a-f43b-415c-8122-4aa23376d575</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 11:26:57</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"SDC_2008_10_2.log</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Changed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>6fb9fad1-51f5-40b2-b05b-d0628f775a3c</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 15:31:52</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"aaaaaa.txt</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Deleted</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>735d74e6-1548-4d7d-9048-ab75dd1c5874</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 20:31:27</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"aa.bmp</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Renamed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>7b36a079-c56c-48f7-9c6e-cf0d77b9c6c1</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 11:27:12</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"SDC_2008_10_2.log</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Changed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>7c2672ac-b210-4eca-9277-2505030e72e5</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 20:39:12</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>d:"aa.png</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Deleted</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>9ab95c19-ccd0-43eb-89ec-3930ebec9a8d</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 21:55:57</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"b.bmp</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Renamed</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>9adb5696-fb6a-497e-b4ff-06f5da896434</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 20:39:12</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>d:"1.png</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Deleted</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>9f4d702f-57c1-46ec-a827-701c2a15ee81</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 23:59:04</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"<span style="font-family: 宋体">新建文件夹</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Created</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c163fa48-f5ea-49b1-95c9-b89f9ee622e5</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>2008-10-02 11:26:42</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>c:"<span style="font-family: 宋体">新建</span> <span style="font-family: 宋体">文本文档</span>.txt</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 128.7pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="172">
<p>Created</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对于新增文件或目录操作其</span>EventStyle<span style="font-family: 宋体">值为</span>Created<span style="font-family: 宋体">，对于修改为</span>Changed<span style="font-family: 宋体">，对于删除为</span>Deleted<span style="font-family: 宋体">，对于重命名为</span>Renamed<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><strong><span style="font-family: 宋体">系统设置信息表</span> SystemConfig</strong><span style="font-family: 宋体">，字段有</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="229">
<p><span style="font-family: 宋体">字段名</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="90">
<p><span style="font-family: 宋体">类型</span></p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e6e6e6; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="367">
<p><span style="font-family: 宋体">说明</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="229">
<p>ConfigName</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="90">
<p><span style="font-family: 宋体">文本</span>(50)</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="367">
<p><span style="font-family: 宋体">系统配置名称</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 171.6pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="229">
<p>ConfigValue</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 67.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="90">
<p><span style="font-family: 宋体">文本</span>(250)</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 275.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="367">
<p><span style="font-family: 宋体">配置数据</span></p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该数据表中保存的数据的范例为</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e0e0e0; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="343">
<p>ConfigName</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: #e0e0e0; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="343">
<p>ConfigValue</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>LogChanged</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>True</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>LogCreated</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>True</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>LogDeleted</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>True</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>LogRenamed</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>False</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>path0</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>c:"*.txt</p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>path1</p></td>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: #ece9d8; width: 257.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="343">
<p>d:"</p></td></tr></table>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">在这里配置项</span>LogChanged<span style="font-family: 宋体">表示是否监视文件内容是否被改变事件，配置项</span>LogCreated<span style="font-family: 宋体">表示是否监视新建文件或目录事件，配置项</span>LogDeleted<span style="font-family: 宋体">表示是否监视文件或目录删除事件，配置项</span>LogRenamed<span style="font-family: 宋体">表示是否监视文件或目录重命名事件。而</span>path0<span style="font-family: 宋体">，</span>path1<span style="font-family: 宋体">，</span>path2<span style="font-family: 宋体">等表示监视的路径，支持通配符。系统配置中可以有若干个</span>path<span style="font-family: 宋体">配置项。</span></p>
<h3><span style="font-family: 宋体">文件系统监视功能设计</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们可以使用</span>System.IO.FileSystemWatcher<span style="font-family: 宋体">来监视文件系统的对象的修改，我们可以使用它的</span>Path<span style="font-family: 宋体">属性来设置要监视的文件夹，使用</span>Filter<span style="font-family: 宋体">属性来设置文件名过滤器，然后响应它的</span>Changed<span style="font-family: 宋体">事件来处理文件内容修改操作，响应</span>Created<span style="font-family: 宋体">事件来处理新增文件或目录操作，响应</span>Deleted<span style="font-family: 宋体">事件来处理删除文件或目录操作，响应</span>Renamed<span style="font-family: 宋体">事件来处理文件和目录重命名操作。这这里我们简单是将这些事件信息保存到数据表</span>FileSystemLog<span style="font-family: 宋体">中。程序在监视文件系统前会读取系统配置信息表</span>SystemConfig<span style="font-family: 宋体">中读取配置信息，根据其中的</span>path<span style="font-family: 宋体">配置项目创建若干个</span>FileSystemWatcher<span style="font-family: 宋体">对象展开监视。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们选定服务的名称为&#8220;</span><strong><span style="color: red">MyFileSystemWatcher</span></strong><span style="font-family: 宋体">&#8221;。</span></p>
<h3><span style="font-family: 宋体">客户端设计</span></h3>
<p><span style="font-family: 宋体">本软件的客户端具有一个图形化用户界面，其界面设计如下</span></p>
<table style="border-right: medium none; border-top: medium none; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt;background: navy; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 293.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid" valign="top" width="391">
<p><strong><span style="color: white; font-family: 宋体">客户端主窗体</span></strong></p></td></tr>
<tr style="height: 23.4pt">
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 293.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; height: 23.4pt; background-color: transparent" width="391">
<p><span style="font-family: 宋体">工具条：<span style="border-right: windowtext 0.5pt solid; padding-right: 0cm; border-top: windowtext 0.5pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; padding-top: 0cm; border-bottom: windowtext 0.5pt solid">刷新</span></span> <span style="border-right: windowtext 0.5pt solid; padding-right: 0cm; border-top: windowtext 0.5pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; font-family: 宋体">删除记录</span> <span style="border-right: windowtext 0.5pt solid; padding-right: 0cm; border-top: windowtext 0.5pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; font-family: 宋体">系统配置</span> <span style="border-right: windowtext 0.5pt solid; padding-right: 0cm; border-top: windowtext 0.5pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; font-family: 宋体">启动服务</span> <span style="border-right: windowtext 0.5pt solid; padding-right: 0cm; border-top: windowtext 0.5pt solid; padding-left: 0cm; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; font-family: 宋体">停止服务</span></p></td></tr>
<tr style="height: 85.85pt">
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 293.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; height: 85.85pt; background-color: transparent" width="391">
<p><span style="font-family: 宋体">数据列表</span></p>
<p><span style="font-family: 宋体">显示从</span> FileSystemLog<span style="font-family: 宋体">表查询所得的数据</span></p></td></tr>
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 293.4pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="391">
<p><span style="font-family: 宋体">状态栏</span></p></td></tr></table>
<p><span style="font-family: 宋体">此外还有一个系统配置对话框，用于查看和修改数据表</span>SystemConfig<span style="font-family: 宋体">中保存的系统配置信息。</span></p>
<h2><span style="font-family: 黑体">软件说明</span></h2>
<p><span style="font-family: 宋体">根据上述的软件设计，我已经把软件编写完毕，现对该软件结构进行说明</span></p>
<h3><span style="font-family: 宋体">客户端主界面</span> frmClient</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">本软件为一个</span>C#<span style="font-family: 宋体">编写的</span>EXE<span style="font-family: 宋体">，主要包含服务端软件模块和客户端软件模块。首先对比较好理解的具有图形化用户界面的客户端模块进行说明，客户端的主界面为</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="437" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/service-client-ui.png" width="585" border="0" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个界面主要功能是数据库信息管理，最上面为一个工具条，中间大部分的一个</span>ListView<span style="font-family: 宋体">控件，最下面为状态栏。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对于</span>ListView<span style="font-family: 宋体">控件其内容是分组的，因此需要设计其分组信息，在</span>VS.NET<span style="font-family: 宋体">的窗体设计器中我们点中</span>ListView<span style="font-family: 宋体">控件，在旁边的属性列表中选择</span>Groups<span style="font-family: 宋体">属性，点击旁边的小按钮可以弹出分组设计器。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="630" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/propertylist-listview-gourp.png" width="551" border="0" /></span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">使用这个分组编辑器我们可以很容易的设计该</span>ListView<span style="font-family: 宋体">控件的分组信息。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这个窗体的加载事件处理为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 服务已经安装标记</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> <span style="color: blue">bool bolServiceInstalled = <span style="color: blue">false</span> ;</span></p>
<p>&nbsp;</p>
<p><span style="color: blue">private</span> <span style="color: blue">void frmViewLog_Load(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">try</span> </span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.ServiceProcess.<span style="color: #2b91af">ServiceController</span> control = <span style="color: blue">new</span> System.ServiceProcess.<span style="color: #2b91af">ServiceController</span>(<span style="color: #a31515">"MyFileSystemWatcher"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.ServiceProcess.<span style="color: #2b91af">ServiceControllerStatus</span> status = control.Status;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; control.Dispose();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolServiceInstalled = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">catch</span>( <span style="color: #2b91af">Exception</span> ext )</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lblServiceInstall.Text = <span style="color: #a31515">"服务尚未安装"</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myTimer.Enabled = <span style="color: blue">false</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnStartService.Enabled = <span style="color: blue">false</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnStopService.Enabled = <span style="color: blue">false</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolServiceInstalled = <span style="color: blue">false</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">MessageBox</span>.Show( <span style="color: blue">this</span>,<span style="color: #a31515">"服务尚未安装:"</span> + ext.Message , <span style="color: #a31515">"系统错误"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.btnRefresh_Click(<span style="color: blue">null</span>, <span style="color: blue">null</span>);</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这里我们首先创建一个联系到文件监视服务的</span>ServiceController<span style="font-family: 宋体">，调用它的</span>Status<span style="font-family: 宋体">属性，若一切正常则表示服务已经安装，我们设置</span>bolServiceInstalled<span style="font-family: 宋体">的标志变量，若发生错误则服务尚未安装，则显示&#8220;服务尚未安装&#8221;的提示信息。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">对于工具条的&#8220;刷新列表&#8221;按钮，其点击事件处理为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">void btnRefresh_Click(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.Cursor = System.Windows.Forms.<span style="color: #2b91af">Cursors</span>.WaitCursor;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; lvwRecord.BeginUpdate();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">try</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvwRecord.Items.Clear();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.Data.<span style="color: #2b91af">IDbCommand</span> cmd = <span style="color: #2b91af">Util</span>.DBConnection.CreateCommand())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = <span style="color: #a31515">"Select RecordID , ObjectName , WatchTime , EventStyle From FileSystemLog order by WatchTime"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Data.<span style="color: #2b91af">IDataReader</span> reader = cmd.ExecuteReader();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">while</span> (reader.Read())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">ListViewItem</span> NewItem = <span style="color: blue">new</span> <span style="color: #2b91af">ListViewItem</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;NewItem.Tag = <span style="color: #2b91af">Convert</span>.ToString(reader.GetValue(0));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.Text = <span style="color: #2b91af">Convert</span>.ToString(reader.GetValue(1));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.SubItems.Add(<span style="color: #2b91af">Convert</span>.ToString(reader.GetValue(2)));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> Style = <span style="color: #2b91af">Convert</span>.ToString(reader.GetValue(3));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.SubItems.Add(Style);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Style = Style.Trim().ToLower();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (Style == <span style="color: #a31515">"created"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.Group = lvwRecord.Groups[0];</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.ImageIndex = 0;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span> <span style="color: blue">if</span> (Style == <span style="color: #a31515">"changed"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.Group = lvwRecord.Groups[1];</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.ImageIndex = 1;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span> <span style="color: blue">if</span> (Style == <span style="color: #a31515">"deleted"</span>)</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.Group = lvwRecord.Groups[2];</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.ImageIndex = 2;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span> <span style="color: blue">if</span> (Style == <span style="color: #a31515">"renamed"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.Group = lvwRecord.Groups[3];</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.ImageIndex = 3;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NewItem.StateImageIndex = NewItem.ImageIndex;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvwRecord.Items.Add(NewItem);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reader.Close();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myStatus.Text = <span style="color: #a31515">"共列出 "</span> + lvwRecord.Items.Count + <span style="color: #a31515">" 个记录"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ext)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">MessageBox</span>.Show(ext.ToString(), <span style="color: #a31515">"系统错误"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.Cursor = System.Windows.Forms.<span style="color: #2b91af">Cursors</span>.Default;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; lvwRecord.EndUpdate();</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在该按钮事件处理中，我们查询数据表</span>FileSystemLog<span style="font-family: 宋体">，对每一条查询所得的数据创建一个</span>ListViewItem<span style="font-family: 宋体">项目，并根据记录的</span>EventStyle<span style="font-family: 宋体">值设置该列表项目的图标序号和分组状态。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">工具条的&#8220;删除记录&#8221;按钮用于删除列表中选择的项目，其点击事件处理为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">void btnDelete_Click(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (lvwRecord.SelectedItems.Count &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.Data.<span style="color: #2b91af">IDbCommand</span> cmd = <span style="color: #2b91af">Util</span>.DBConnection.CreateCommand())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">for</span> (<span style="color: blue">int</span> iCount = lvwRecord.Items.Count - 1; iCount &gt;= 0; iCount--)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">ListViewItem</span> item = lvwRecord.Items[iCount];</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (item.Selected)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = <span style="color: #a31515">"Delete From FileSystemLog Where RecordID = '"</span> + item.Tag + <span style="color: #a31515">"'"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lvwRecord.Items.Remove(item);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//for</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//using</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在刷新列表中，我们将列表项目的</span>Tag<span style="font-family: 宋体">属性值设置为数据库记录的编号，在这里我们利用这个事先保存的数据库记录的编号拼凑出</span>SQL<span style="font-family: 宋体">语句然后删除指定的记录。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">工具条的&#8220;启动服务&#8221;按钮用于启动后台的文件监视服务。其点击事件处理为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">void btnStartService_Click(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolServiceInstalled == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.ServiceProcess.<span style="color: #2b91af">ServiceController</span> control = <span style="color: blue">new</span> System.ServiceProcess.<span style="color: #2b91af">ServiceController</span>(<span style="color: #a31515">"MyFileSystemWatcher"</span>))</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (control.Status == System.ServiceProcess.<span style="color: #2b91af">ServiceControllerStatus</span>.Stopped)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; control.Start();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这里我们创建一个</span>ServiceController<span style="font-family: 宋体">对象，若判断出服务的状态为停止，则调用控制器的</span>Start<span style="font-family: 宋体">方法来启动服务，在这里</span>Start<span style="font-family: 宋体">方法内部只是通知操作系统启动指定名称的服务，它发送通知后立即返回，并不会等待服务启动后返回。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类似的对于&#8220;停止服务&#8221;，其点击事件处理为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">void btnStopService_Click(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolServiceInstalled == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.ServiceProcess.<span style="color: #2b91af">ServiceController</span> control = <span style="color: blue">new</span> System.ServiceProcess.<span style="color: #2b91af">ServiceController</span>(<span style="color: #a31515">"MyFileSystemWatcher"</span>))</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (control.Status == System.ServiceProcess.<span style="color: #2b91af">ServiceControllerStatus</span>.Running)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; control.Stop();</span></p>
<p><span>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这个处理过程中，若判断出服务状态为运行中，则调用控制器的</span>Stop<span style="font-family: 宋体">方法来停止服务。在这里</span>Stop<span style="font-family: 宋体">方法内部只是通知操作系统停止指定的服务，它发送通知后立即返回，不会等待服务停止后返回。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们还在窗体上放置一个定时器控件，定时间隔为</span>2<span style="font-family: 宋体">秒，用于根据服务的状态刷新工具条按钮状态，其定时事件处理为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">void myTimer_Tick(<span style="color: blue">object</span> sender, <span style="color: #2b91af">EventArgs</span> e)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (bolServiceInstalled == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p>&nbsp;<span>&nbsp;&nbsp; <span style="color: blue">using</span> (System.ServiceProcess.<span style="color: #2b91af">ServiceController</span> control = <span style="color: blue">new</span> System.ServiceProcess.<span style="color: #2b91af">ServiceController</span>(<span style="color: #a31515">"MyFileSystemWatcher"</span>))</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnStartService.Enabled = (control.Status == System.ServiceProcess.<span style="color: #2b91af">ServiceControllerStatus</span>.Stopped);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; btnStopService.Enabled = (control.Status == System.ServiceProcess.<span style="color: #2b91af">ServiceControllerStatus</span>.Running);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这里我们创建了一个绑定到文件系统监控服务的</span>ServiceController<span style="font-family: 宋体">对象，然后根据它的</span>Status<span style="font-family: 宋体">状态来设置&#8220;启动服务&#8221;和&#8220;停止服务&#8221;按钮的可用状态。</span></p>
<h3><span style="font-family: 宋体">系统配置对话框</span> dlgConfig</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在客户端主窗体中点击工具条的&#8220;系统配置&#8221;按钮就会弹出系统设置对话框，该对话框的用户界面为<img height="340" alt="" src="http://images.cnblogs.com/cnblogs_com/xdesigner/service-config.png" width="485" border="0" /></span></p>
<p style="text-indent: 21pt"></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该对话框比较简单，就是用于显示和修改系统配置信息对象</span>MyConfig<span style="font-family: 宋体">中的内容。由于文件系统监视服务只有在启动的时候读取系统配置信息，因此对系统配置的任何修改都需要重新启动服务才能生效。</span></p>
<h3><span style="font-family: 宋体">系统配置信息对象</span> MyConfig</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">系统配置信息对象</span>MyConfig<span style="font-family: 宋体">用于读取和修改保存在数据表</span>SystemConfig<span style="font-family: 宋体">中的系统配置信息。其包含的配置信息的代码如下</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">bool bolLogRenamed = <span style="color: blue">true</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 是否记录重命名事件</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool LogRenamed</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> bolLogRenamed; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { bolLogRenamed = <span style="color: blue">value</span>; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: blue">private</span> <span style="color: blue">bool bolLogChanged = <span style="color: blue">true</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 是否记录文件修改事件</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool LogChanged</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> bolLogChanged; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { bolLogChanged = <span style="color: blue">value</span>; }</span></p>
<p>}</p>
<p><span style="color: blue">private</span> <span style="color: blue">bool bolLogCreated = <span style="color: blue">true</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 是否记录对象创建事件</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool LogCreated</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> bolLogCreated; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { bolLogCreated = <span style="color: blue">value</span>; }</span></p>
<p>}</p>
<p><span style="color: blue">private</span> <span style="color: blue">bool bolLogDeleted = <span style="color: blue">true</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 是否记录对象删除事件</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">bool LogDeleted</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> bolLogDeleted; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { bolLogDeleted = <span style="color: blue">value</span>; }</span></p>
<p>}</p>
<p>&nbsp;</p>
<p><span style="color: blue">private</span> <span style="color: blue">string[] myWatchedPaths = <span style="color: blue">null</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 监视的目录</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">string[] WatchedPaths</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span> { <span style="color: blue">return</span> myWatchedPaths; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">set</span> { myWatchedPaths = <span style="color: blue">value</span>; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">它的</span>Load<span style="font-family: 宋体">方法用于从数据库中加载配置信息，其处理过程为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>public void Load()</p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; myWatchedPaths = null;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; System.Collections.<span style="color: #2b91af">ArrayList</span> paths = new System.Collections.<span style="color: #2b91af">ArrayList</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; using (System.Data.<span style="color: #2b91af">IDbCommand</span> cmd = <span style="color: #2b91af">Util</span>.DBConnection.CreateCommand())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = <span style="color: #a31515">"Select ConfigName , ConfigValue From SystemConfig"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Data.<span style="color: #2b91af">IDataReader</span> reader = cmd.ExecuteReader();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (reader.Read())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string Name = <span style="color: #2b91af">Convert</span>.ToString(reader.GetValue(0));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Name == null)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Name = Name.Trim().ToLower();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string Value = <span style="color: #2b91af">Convert</span>.ToString(reader.GetValue(1));</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Name.StartsWith(<span style="color: #a31515">"path"</span>))</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paths.Add(Value.Trim());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (Name == <span style="color: #a31515">"logrenamed"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bolLogRenamed = <span style="color: #2b91af">Convert</span>.ToBoolean(Value);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (Name == <span style="color: #a31515">"logchanged"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolLogChanged = <span style="color: #2b91af">Convert</span>.ToBoolean(Value);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (Name == <span style="color: #a31515">"logdeleted"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bolLogDeleted = <span style="color: #2b91af">Convert</span>.ToBoolean(Value);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (Name == <span style="color: #a31515">"logcreated"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bolLogCreated = <span style="color: #2b91af">Convert</span>.ToBoolean(Value);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; myWatchedPaths = (string[])paths.ToArray(typeof(string));</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在该方法中程序查询数据表</span>SystemConfig<span style="font-family: 宋体">中的配置项目名称和数据，若项目名称以&#8220;</span>path<span style="font-family: 宋体">&#8221;开头则为要监视的路径，而配置项</span>logrenamed<span style="font-family: 宋体">，</span>logchanged<span style="font-family: 宋体">，</span>logdeleted<span style="font-family: 宋体">，</span>logcreated<span style="font-family: 宋体">分别表示是否监视文件目录重命名，修改，删除和新建等操作。</span></p>
<p style="text-indent: 21pt">MyConfig<span style="font-family: 宋体">对象还有一个</span>Save<span style="font-family: 宋体">方法用于将系统配置信息保存到数据库中，其处理过程为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>public void Save()</p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; using (System.Data.<span style="color: #2b91af">IDbCommand</span> cmd = <span style="color: #2b91af">Util</span>.DBConnection.CreateCommand())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = <span style="color: #a31515">"Delete From SystemConfig"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = <span style="color: #a31515">"Insert Into SystemConfig ( ConfigName , ConfigValue ) Values( ? , ? )"</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Data.<span style="color: #2b91af">IDbDataParameter</span> pName = cmd.CreateParameter();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.Parameters.Add( pName );</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Data.<span style="color: #2b91af">IDbDataParameter</span> pValue = cmd.CreateParameter();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.Parameters.Add( pValue );</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pName.Value = <span style="color: #a31515">"LogRenamed"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pValue.Value = bolLogRenamed.ToString();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pName.Value = <span style="color: #a31515">"LogChanged"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pValue.Value = bolLogChanged.ToString();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pName.Value = <span style="color: #a31515">"LogDeleted"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pValue.Value = bolLogDeleted.ToString();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pName.Value = <span style="color: #a31515">"LogCreated"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pValue.Value = bolLogCreated.ToString();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int iCount = 0; iCount &lt; myWatchedPaths.Length; iCount++)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string path = myWatchedPaths[ iCount ] ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( path == null || path.Trim().Length == 0 )</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pName.Value = <span style="color: #a31515">"path"</span>&nbsp;+ iCount ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pValue.Value = path ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这个方法中，首先删除数据表</span>SystemConfig<span style="font-family: 宋体">中所有的记录，然后将所有的配置信息保存到数据表</span>SystemConfig<span style="font-family: 宋体">中。</span></p>
<h3><span style="font-family: 宋体">文件系统监视服务</span> MyFileSystemWatcherService</h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类</span>MyFileSystemWatcherService<span style="font-family: 宋体">就是文件系统监视服务，它是从</span>ServiceBase<span style="font-family: 宋体">派生的，首先说明一下执行文件系统监视的功能性的过程，其代码如下</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 文件系统监视器列表</span></p>
<p>/// &lt;/summary&gt;</p>
<p><span style="color: blue">private</span> System.Collections.<span style="color: #2b91af">ArrayList myWatchers = <span style="color: blue">null</span>;</span></p>
<p>&nbsp;</p>
<p>/// &lt;summary&gt;</p>
<p>///<span style="color: green"> 开始启动文件系统监视</span></p>
<p>/// &lt;/summary&gt;</p>
<p>/// &lt;returns&gt;<span style="color: green">操作是否成功&lt;/returns&gt;</span></p>
<p><span style="color: blue">internal</span> <span style="color: blue">bool StartFileSystemWatching()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; myWatchers = <span style="color: blue">new</span> System.Collections.<span style="color: #2b91af">ArrayList</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">MyConfig</span>.Instance.Load();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span>[] paths = <span style="color: #2b91af">MyConfig</span>.Instance.WatchedPaths;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; System.Text.<span style="color: #2b91af">StringBuilder</span> myPathList = <span style="color: blue">new</span> <span style="color: #2b91af">StringBuilder</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (paths != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: blue">string</span> path <span style="color: blue">in</span> paths)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (System.IO.<span style="color: #2b91af">Path</span>.IsPathRooted(path) == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">continue</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> BasePath = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> Filter = <span style="color: blue">null</span>;</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (System.IO.<span style="color: #2b91af">Directory</span>.Exists(path))</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BasePath = path;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Filter = <span style="color: #a31515">"*.*"</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span></span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BasePath = System.IO.<span style="color: #2b91af">Path</span>.GetDirectoryName(path);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Filter = System.IO.<span style="color: #2b91af">Path</span>.GetFileName(path);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (BasePath == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">continue</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BasePath = BasePath.Trim();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (BasePath.ToUpper().StartsWith(System.Windows.Forms.<span style="color: #2b91af">Application</span>.StartupPath))</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 不能监视程序本身所在的目录的文件系统更改</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">continue</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (System.IO.<span style="color: #2b91af">Directory</span>.Exists(BasePath) == <span style="color: blue">false</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 不能监视不存在的目录</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">continue</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myPathList.Length &gt; 0)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;{</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myPathList.Append(<span style="color: #a31515">";"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myPathList.Append(path);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IO.<span style="color: #2b91af">FileSystemWatcher</span> watcher = <span style="color: blue">new</span> System.IO.<span style="color: #2b91af">FileSystemWatcher</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.Path = BasePath;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.Filter = Filter;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.EnableRaisingEvents = <span style="color: blue">true</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.IncludeSubdirectories = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: #2b91af">MyConfig</span>.Instance.LogChanged)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.Changed += <span style="color: blue">delegate</span>(<span style="color: blue">object</span> sender, System.IO.<span style="color: #2b91af">FileSystemEventArgs</span> args)</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteFileSystemLog(args.FullPath, args.ChangeType.ToString());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: #2b91af">MyConfig</span>.Instance.LogCreated)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.Created += <span style="color: blue">delegate</span>(<span style="color: blue">object</span> sender, System.IO.<span style="color: #2b91af">FileSystemEventArgs</span> args)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteFileSystemLog(args.FullPath, args.ChangeType.ToString());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: #2b91af">MyConfig</span>.Instance.LogDeleted)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watcher.Deleted += <span style="color: blue">delegate</span>(<span style="color: blue">object</span> sender, System.IO.<span style="color: #2b91af">FileSystemEventArgs</span> args)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteFileSystemLog(args.FullPath, args.ChangeType.ToString());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (<span style="color: #2b91af">MyConfig</span>.Instance.LogRenamed)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watcher.Renamed += <span style="color: blue">delegate</span>(<span style="color: blue">object</span> sender, System.IO.<span style="color: #2b91af">RenamedEventArgs</span> args)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteFileSystemLog(args.FullPath, args.ChangeType.ToString());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;};</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myWatchers.Add(watcher);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<span style="color: green">//foreach</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.EventLog.WriteEntry(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #a31515">"开始监视文件系统 "</span> + myPathList.ToString(),</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">EventLogEntryType</span>.Information);</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }<span style="color: green">//if</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> <span style="color: blue">true</span>;</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在这个过程中，首先使用</span>MyConfig.Load<span style="font-family: 宋体">从数据库中加载系统配置，然后遍历所有需要监视的路径，对其中的每个路径解析出目录名和文件名，然后创建一个</span>FileSystemWatcher<span style="font-family: 宋体">对象，设置其</span>Path<span style="font-family: 宋体">和</span>Filter<span style="font-family: 宋体">属性，还根据</span>MyConfig<span style="font-family: 宋体">中的系统配置来绑定监视对象的</span>Changed<span style="font-family: 宋体">事件，</span>Created<span style="font-family: 宋体">事件，</span>Deleted<span style="font-family: 宋体">事件和</span>Renamed<span style="font-family: 宋体">事件，以实现对文件系统的监视。这里绑定事件的代码使用了</span>C#2.0<span style="font-family: 宋体">的匿名委托的语法功能。设置</span>FileSystemWatcher<span style="font-family: 宋体">对象后将该对象添加到文件系统监视器列表</span>myWatchers<span style="font-family: 宋体">中。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">启动服务后使用</span>EventLog.WriteEntry<span style="font-family: 宋体">向</span>Windows<span style="font-family: 宋体">系统事件日志添加一些日志信息。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这里使用了一个</span>WriteFileSystemLog<span style="font-family: 宋体">方法，该方法代码为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">void WriteFileSystemLog(<span style="color: blue">string</span> ObjectName, <span style="color: blue">string</span> EventStyle )</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; System.Data.<span style="color: #2b91af">IDbConnection</span> conn = <span style="color: #2b91af">Util</span>.DBConnection;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (conn == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 将监视结果添加到数据库中</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (System.Data.<span style="color: #2b91af">IDbCommand</span> cmd = conn.CreateCommand())</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.CommandText = <span style="color: #a31515">"Insert Into FileSystemLog ( RecordID , WatchTime , ObjectName , EventStyle ) Values ( '"</span> + System.<span style="color: #2b91af">Guid</span>.NewGuid().ToString() + <span style="color: #a31515">"' , '"</span> + <span style="color: #2b91af">DateTime</span>.Now.ToString(<span style="color: #a31515">"yyyy-MM-dd HH:mm:ss"</span>) + <span style="color: #a31515">"' , ? , '"</span> + EventStyle + <span style="color: #a31515">"')"</span> ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Data.<span style="color: #2b91af">IDbDataParameter</span> p = cmd.CreateParameter();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p.Value = ObjectName;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.Parameters.Add(p);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmd.ExecuteNonQuery();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">该方法参数是记录的文件或目录名，以及事件类型，程序首先拼凑出一个</span>Insert<span style="font-family: 宋体">的</span>SQL<span style="font-family: 宋体">语句，然后向数据表</span>FileSystemLog<span style="font-family: 宋体">添加一条数据。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">类型</span>MyFileSystemWatcherService<span style="font-family: 宋体">还重载了</span>ServiceBase<span style="font-family: 宋体">的</span>OnStart<span style="font-family: 宋体">，</span>OnStop<span style="font-family: 宋体">，</span>OnPause<span style="font-family: 宋体">，</span>OnContinue<span style="font-family: 宋体">等方法来响应外界对服务过程的控制。</span></p>
<p style="text-indent: 21pt">OnStart<span style="font-family: 宋体">方法的代码如下，该方法调用</span>StartFileSystemWatching<span style="font-family: 宋体">函数就算完成了启动服务的操作。</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">protected</span> <span style="color: blue">override <span style="color: blue">void</span> OnStart(<span style="color: blue">string</span>[] args)</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">this</span>.StartFileSystemWatching();</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">OnStop<span style="font-family: 宋体">方法的代码如下，该方法首先销毁掉所有正在运行的文件系统监视器，然后关闭数据库连接。</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">protected</span> <span style="color: blue">override <span style="color: blue">void</span> OnStop()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myWatchers != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (System.IO.<span style="color: #2b91af">FileSystemWatcher</span> w <span style="color: blue">in</span> myWatchers)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; w.EnableRaisingEvents = <span style="color: blue">false</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; w.Dispose();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myWatchers = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">Util</span>.CloseDBConnection();</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">base</span>.OnStop();</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">OnPause<span style="font-family: 宋体">方法代码如下，该方法设置所有的文件系统监视器不触发事件，这样软件不能感知文件系统的修改，因此也就暂停了对文件系统的监视。</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>protected override void OnPause()</p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; if (myWatchers != null)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (System.IO.<span style="color: #2b91af">FileSystemWatcher</span> w in myWatchers)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; w.EnableRaisingEvents = false;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; base.OnPause();</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">OnContinue<span style="font-family: 宋体">方法的代码如下，该方法重新设置所有的文件系统监视器能触发事件，因此软件又能监视文件系统的修改了。</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>protected override void OnContinue()</p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; if (myWatchers != null)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (System.IO.<span style="color: #2b91af">FileSystemWatcher</span> w in myWatchers)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; w.EnableRaisingEvents = true ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; base.OnContinue();</span></p>
<p>}</p></td></tr></table>
<h3><span style="font-family: 宋体">管理数据库连接</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 新宋体">类型Util用于管理数据库连接，其代码为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p><span style="color: blue">private</span> <span style="color: blue">static System.Data.<span style="color: #2b91af">IDbConnection</span> myDBConnection = <span style="color: blue">null</span>;</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 获得数据库连接对象</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">static System.Data.<span style="color: #2b91af">IDbConnection</span> DBConnection</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">get</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myDBConnection == <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myDBConnection = <span style="color: blue">new</span> System.Data.OleDb.<span style="color: #2b91af">OleDbConnection</span>(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #a31515">"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="""</span> </span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; + System.IO.<span style="color: #2b91af">Path</span>.Combine(</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Windows.Forms.<span style="color: #2b91af">Application</span>.StartupPath,</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #a31515">"FileSystemWatcher.mdb"</span>) + <span style="color: #a31515">""""</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myDBConnection.Open();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span> myDBConnection;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;summary&gt;</span></p>
<p><span style="color: gray">///</span><span style="color: green"> 关闭数据库连接</span></p>
<p><span style="color: gray">///</span> <span style="color: gray">&lt;/summary&gt;</span></p>
<p><span style="color: blue">public</span> <span style="color: blue">static <span style="color: blue">void</span> CloseDBConnection()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (myDBConnection != <span style="color: blue">null</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myDBConnection.Close();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myDBConnection = <span style="color: blue">null</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt"><span style="font-family: 宋体">从这个代码可以看出软件使用的数据库是应用程序目录下的</span>FileSystemWatcher.mdb<span style="font-family: 宋体">数据库。为了提高效率，减少数据库的连接次数，服务在运行其间只连接一次数据库，使用完毕后不断开，只有退出软件时才断开数据库连接。</span></p>
<h3><span style="font-family: 宋体">启动程序</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在类型</span>Program<span style="font-family: 宋体">中定义了</span>Main<span style="font-family: 宋体">函数，该函数就是本软件的启动入口方法。其代码为</span></p>
<table style="border-right: medium none; border-top: medium none;background: #f3f3f3; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" bgcolor="#f3f3f3" border="1">
<tr>
<td style="border-right: windowtext 0.5pt solid; padding-right: 5.4pt; border-top: windowtext 0.5pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 0.5pt solid; width: 514.8pt; padding-top: 0cm; border-bottom: windowtext 0.5pt solid; background-color: transparent" valign="top" width="686">
<p>[System.<span style="color: #2b91af">STAThread()]</span></p>
<p><span style="color: blue">static</span> <span style="color: blue">void Main()</span></p>
<p>{</p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">try</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.<span style="color: #2b91af">Uri</span> uri = <span style="color: blue">new</span> <span style="color: #2b91af">Uri</span>(<span style="color: blue">typeof</span>(<span style="color: blue">string</span>).Assembly.CodeBase);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> RuntimePath = System.IO.<span style="color: #2b91af">Path</span>.GetDirectoryName( uri.LocalPath ) ;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">string</span> strInstallUtilPath = System.IO.<span style="color: #2b91af">Path</span>.Combine(RuntimePath, <span style="color: #a31515">"InstallUtil.exe"</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">foreach</span> (<span style="color: blue">string</span> arg <span style="color: blue">in</span> System.<span style="color: #2b91af">Environment</span>.GetCommandLineArgs())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">Console</span>.WriteLine(arg);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">if</span> (arg == <span style="color: #a31515">"/install"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Diagnostics.<span style="color: #2b91af">Process</span>.Start(strInstallUtilPath, <span style="color: #a31515">""""</span> + System.Windows.Forms.<span style="color: #2b91af">Application</span>.ExecutablePath + <span style="color: #a31515">""""</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span> <span style="color: blue">if</span> (arg == <span style="color: #a31515">"/uninstall"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p>&nbsp;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Diagnostics.<span style="color: #2b91af">Process</span>.Start(strInstallUtilPath, <span style="color: #a31515">"/u """</span> + System.Windows.Forms.<span style="color: #2b91af">Application</span>.ExecutablePath + <span style="color: #a31515">""""</span>);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span> <span style="color: blue">if</span> (arg == <span style="color: #a31515">"/client"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">// 启动客户端</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2b91af">Application</span>.EnableVisualStyles();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">Application</span>.SetCompatibleTextRenderingDefault(<span style="color: blue">false</span>);</span></p>
<p>&nbsp;</p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">using</span> (<span style="color: #2b91af">frmClient</span> frm = <span style="color: blue">new</span> <span style="color: #2b91af">frmClient</span>())</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">Application</span>.Run(frm);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: green">//frm.ShowDialog();</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">Util</span>.CloseDBConnection();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">else</span> <span style="color: blue">if</span> (arg == <span style="color: #a31515">"/debug"</span>)</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">MyFileSystemWatcherService</span> service = <span style="color: blue">new</span> <span style="color: #2b91af">MyFileSystemWatcherService</span>();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; service.StartFileSystemWatching();</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Threading.<span style="color: #2b91af">Thread</span>.Sleep(1000 * 600);</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> ext)</span></p>
<p><span>&nbsp;&nbsp;&nbsp; {</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">Console</span>.WriteLine(ext.ToString());</span></p>
<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: blue">return</span>;</span></p>
<p>&nbsp;<span>&nbsp;&nbsp; }</span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: green">// 运行服务对象</span></span></p>
<p><span>&nbsp;&nbsp;&nbsp; <span style="color: #2b91af">ServiceBase</span>.Run( <span style="color: blue">new</span> <span style="color: #2b91af">MyFileSystemWatcherService</span>());</span></p>
<p>}</p></td></tr></table>
<p style="text-indent: 21pt">Main<span style="font-family: 宋体">函数决定调用本软件的那个功能模块，由于</span>Main<span style="font-family: 宋体">函数本身具有安装和卸载服务的功能，首先得找到微软</span>.NET<span style="font-family: 宋体">框架所带的</span>InstallUtil.exe<span style="font-family: 宋体">的完整的路径。微软</span>.NET<span style="font-family: 宋体">编程中，基础类型</span>string<span style="font-family: 宋体">属于</span>mscorlib.dll<span style="font-family: 宋体">，因此可以使用</span><span style="color: blue">typeof(string).Assembly.CodeBase</span><span style="font-family: 宋体">获得文件</span>mscorlib.dll<span style="font-family: 宋体">的绝对路径名，而</span>InstallUtil.exe<span style="font-family: 宋体">和</span>mscorlib.dll<span style="font-family: 宋体">是同一个目录的，因此也就能获得</span>InstallUtil.exe<span style="font-family: 宋体">的绝对路径名了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们使用</span>System.Environment.GetCommandLineArgs()<span style="font-family: 宋体">获得所有的命令行参数。遍历所有的参数，若存在&#8220;</span>/install<span style="font-family: 宋体">&#8221;则表示要安装服务，于是调用</span>InstallUtil.exe<span style="font-family: 宋体">来将软件本身注册为服务，若遇到&#8220;</span>/uninstall<span style="font-family: 宋体">&#8221;则调用</span>InstallUtil.exe<span style="font-family: 宋体">卸载服务，若遇到&#8220;</span>/client<span style="font-family: 宋体">&#8221;则调用客户端模块，若遇到&#8220;</span>/debug<span style="font-family: 宋体">&#8221;则创建服务对象，调用它的</span><span style="color: blue">StartFileSystemWatching</span><span style="font-family: 宋体">模拟启动服务，然后主线程阻塞掉，但此时文件系统监视的功能性模块还在运行，可以设置断点进行调试。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">若没有遇到任何可识别的命令行参数，则调用</span>ServiceBase.Run<span style="font-family: 宋体">函数来执行服务。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">由于向</span>Windows<span style="font-family: 宋体">系统注册自己为服务时没有指明任何命令行参数，因此服务管理器启动进程时不会添加任何命令行参数，因此本程序也就是以服务模式运行。若在</span>Windows<span style="font-family: 宋体">资源管理器中双击执行程序时也是以服务模式运行，此时没有相关的运行环境，程序启动后会报错。此时必须添加程序代码可识别的命令行参数。</span></p>
<h2><span style="font-family: 黑体">运行软件</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">程序编写完毕，编译通过，生成一个</span>MyWindowsService.exe<span style="font-family: 宋体">文件，我们就可以开始运行这个软件了。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">首先我们得向系统注册服务，我们可以使用命令行&#8220;<span style="color: blue">程序路径</span></span><span style="color: blue">/MyWindowsService.exe /install</span><span style="font-family: 宋体">&#8221;来注册服务，也可以直接运行&#8220;<span style="color: blue">微软</span></span><span style="color: blue">.NET</span><span style="color: blue; font-family: 宋体">框架路径</span><span style="color: blue">/installutil.exe&nbsp;</span><span style="color: blue; font-family: 宋体">程序路径</span><span style="color: blue">/MyWindowsService.exe</span><span style="font-family: 宋体">&#8221;；相反的，我们可以使用命令行&#8220;<span style="color: blue">程序路径</span></span><span style="color: blue">/MyWindowsService.exe /uninstall</span><span style="font-family: 宋体">&#8221;或者&#8220;<span style="color: blue">微软</span></span><span style="color: blue">.NET</span><span style="color: blue; font-family: 宋体">框架路径</span><span style="color: blue">/installutil.exe&nbsp;/u&nbsp;</span><span style="color: blue; font-family: 宋体">程序路径</span><span style="color: blue">/MyWindowsService.exe</span><span style="font-family: 宋体">&#8221;来卸载服务。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">安装服务后，我们可以使用命令行&#8220;<span style="color: blue">程序路径</span></span><span style="color: blue">/MyWindowsService.exe /client</span><span style="font-family: 宋体">&#8221;来运行该服务的客户端软件了。</span></p>
<h2><span style="font-family: 黑体">小结</span></h2>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在本课程中，我们使用</span>C#<span style="font-family: 宋体">编写了一个简单的用于监视文件系统的</span>Windows<span style="font-family: 宋体">服务，包括服务器软件和客户端软件，若使用传统的</span>C++<span style="font-family: 宋体">开发服务这种底层程序需要熟悉大量的</span>API<span style="font-family: 宋体">函数，而微软</span>.NET<span style="font-family: 宋体">框架很好的封装了这些技术细节，简化了编程过程，使得我们可以把主要警力放在提供服务内容的功能性模块的开发上来，从这里可以看出基于微软</span>.NET<span style="font-family: 宋体">框架是可以低成本的开发出一些功能强大的软件。</span></p><img src="http://www.cnblogs.com/xdesigner/aggbug/1430301.html?type=1" width="1" height="1" alt=""/><p>评论: 16　<a href="http://www.cnblogs.com/xdesigner/archive/2009/04/06/1430301.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/04/06/1430301.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>某司法局行政业务综合平台报表应用案例</title><link>http://www.cnblogs.com/xdesigner/archive/2009/02/12/asp_net_web_report.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Thu, 12 Feb 2009 06:23:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/02/12/asp_net_web_report.html</guid><description><![CDATA[<p>阅读: 890 评论: 0 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-02-12 14:23 <a href="http://www.cnblogs.com/xdesigner/archive/2009/02/12/asp_net_web_report.html" target="_blank">原文链接</a></p><p align="center"><strong><span style="font-size: 22pt; font-family: 宋体">某司法局行政业务综合平台报表应用案例</span></strong><strong></strong></p>
<p align="center"><span style="font-family: 宋体">南京擎天科技有限公司</span> 2009-1-16</p>
<h1><span style="font-family: 宋体">前言</span></h1>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在擎天天博报表软件产品人员的支持下</span>,<span style="font-family: 宋体">我们在某司法局行政综合业务平台中成功的使用了天博报表软件产品，低成本高效率的实现了比较复杂的报表功能，在这个项目中突出展现了天博报表软件强大的数据收集和整合能力，此外还体验了天博报表软件强大的设计能力和文档输出能力。<a href="http://www.cnblogs.com/Files/xdesigner/某司法局行政业务综合平台报表应用案例.zip">点击下载案例本文档WORD版本和相关文件《某司法局行政业务综合平台报表应用案例.zip》</a>。</span></p>
<h1><span style="font-family: 宋体">项目介绍</span></h1>
<p style="text-indent: 21pt"><span style="font-family: 宋体">《某司法局行政综合业务平台》是应某司法局的要求开发的一套运行在外网的</span>B/S<span style="font-family: 宋体">系统，具备了基层信息、社区纠正信息、法律援助信息、律师信息和司法行政系统人员信息的综合业务平台。该系统使用</span>C#<span style="font-family: 宋体">语言开发，运行在英特网上。服务器为</span>Windows2003<span style="font-family: 宋体">、</span>IIS6.0<span style="font-family: 宋体">、</span>ASP.NET2.0<span style="font-family: 宋体">和</span>MS SQL Server2000<span style="font-family: 宋体">数据库的运行环境，客户端为</span>IE6.0<span style="font-family: 宋体">。</span>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="557" alt="" src="http://www.cnblogs.com/images/cnblogs_com/xdesigner/image001.jpg" width="660" border="0" />本系统除了需要实现了电子表单、工作流技术外，还存在法律援助申请表、律师业务统计、执业律师统计等</span>30<span style="font-family: 宋体">个报表功能需求。这些报表需要查询过程复杂，报表样式定制工作量大。整个系统的光开发就投入了</span>7<span style="font-family: 宋体">个人月。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">天博报表软件使用过程</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我们使用天博报表软件的过程很简单，首先</span></p>
<h1><span style="font-family: 宋体">天博报表软件使用过程</span></h1>
<p style="text-indent: 21pt"><span style="font-family: 宋体">天博报表软件作为一个比较先进的通用报表软件产品，其使用过程是相当方便的，现在以本系统中的《法律援助申请表》为范例讲解一下。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">第一步，设计报表样式。打开天博报表集成设计环境，参照客户提供的纸质报表的样式设计出报表样式，其设计界面如下。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="596" alt="" src="http://www.cnblogs.com/images/cnblogs_com/xdesigner/image002.jpg" width="680" border="0" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">第二步，设计报表数据源。进入数据源设计界面，在右边的列表中加载分析</span>MS SQL Server2000<span style="font-family: 宋体">的数据库表和字段结构，然后使用拖拽操作来定义树状的报表数据源结构，并手动修改一些</span>SQL<span style="font-family: 宋体">语句。我们可以在在集成设计环境中随时预览报表的执行效果。</span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="596" alt="" src="http://www.cnblogs.com/images/cnblogs_com/xdesigner/image003.jpg" width="680" border="0" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">第三步，使用报表。在</span>VS.NET2005<span style="font-family: 宋体">的</span>ASP.NET<span style="font-family: 宋体">窗体设计器中，将报表</span>WEB<span style="font-family: 宋体">控件拖拽到设计页面中，然后进行一些简单的属性设置。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体"><img height="616" alt="" src="http://www.cnblogs.com/images/cnblogs_com/xdesigner/skywebcontrol.jpg" width="629" border="0" /></span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">第四步，编写代码加载报表模板，连接数据库，执行和显示报表。其代码如下，可以看出在</span>C#<span style="font-family: 宋体">中使用天博报表软件非常简单，加载报表模板文件，连接数据库，设置报表参数，然后执行显示报表即可。</span>&nbsp;&nbsp; </p>
<p><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp; <img height="562" alt="" src="http://www.cnblogs.com/images/cnblogs_com/xdesigner/skyreportsource.jpg" width="671" border="0" /></span></p>
<p><span style="font-family: 宋体">经过如此就完成了一个复杂报表的开发，该报表实际运行效果如下</span></p>
<p><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp; <img height="557" alt="" src="http://www.cnblogs.com/images/cnblogs_com/xdesigner/skyreportrun2.jpg" width="660" border="0" /></span></p>
<p><span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp; 可以看到天博报表在</span>B/S<span style="font-family: 宋体">系统中就能以精确分页的方式来显示和打印报表，并可导出精确分页的</span>WORD<span style="font-family: 宋体">文档。天博报表没有使用任何客户端的组件或插件，使用纯</span>HTML<span style="font-family: 宋体">和图片来完整的展示报表文档，非常适合</span>B/S<span style="font-family: 宋体">系统开发。</span></p>
<p>&nbsp;</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">在该系统的开发中，我们使用相似的步骤实现了</span>30<span style="font-family: 宋体">个报表功能的开发，报表开发过程绝大部分的工作就是使用天博报表集成设计环境来编制报表模板，而且报表模板编制过程无需编程，这样我们就可以使用实习生来完成这个工作，这大大降低了项目开发成本，优化了项目人力资源的使用。</span></p>
<p style="text-indent: 21pt">&nbsp;</p>
<h1><span style="font-family: 宋体">天博报表软件产品支持信息</span></h1>
<p style="text-indent: 21pt"><span style="font-family: 宋体">地址：南京市龙蟠中路</span>168<span style="font-family: 宋体">号江苏软件园</span>50<span style="font-family: 宋体">号楼南京擎天科技有限公司</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">邮编：</span>210002</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">支持电话：</span>025-84815959-024</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">产品官方网站：</span> <a href="http://www.skyreports.cn/">http://www.skyreports.cn/</a></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">产品安装文件下载地址：</span> <a href="http://files.cnblogs.com/xdesigner/SkyReportsSetup.zip">http://files.cnblogs.com/xdesigner/SkyReportsSetup.zip</a></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">技术支持</span>QQ<span style="font-family: 宋体">群：</span> 41118220</p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">电子信箱：</span><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#101;&#112;&#111;&#114;&#116;&#64;&#115;&#107;&#121;&#110;&#106;&#46;&#99;&#111;&#109;">report@skynj.com</a></p>
<img src="http://www.cnblogs.com/xdesigner/aggbug/1389069.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/xdesigner/archive/2009/02/12/asp_net_web_report.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/02/12/asp_net_web_report.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>对软件公司财务管理方面的一些想法</title><link>http://www.cnblogs.com/xdesigner/archive/2009/01/06/1370273.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Tue, 06 Jan 2009 05:46:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2009/01/06/1370273.html</guid><description><![CDATA[<p>阅读: 716 评论: 0 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2009-01-06 13:46 <a href="http://www.cnblogs.com/xdesigner/archive/2009/01/06/1370273.html" target="_blank">原文链接</a></p><p style="text-indent: 21pt"><span style="font-family: 宋体">近期在某公司战略研讨会议中看到了一些公司内部财务报表，深有感触，我虽然作为一个软件开发人员，却在此提出个人的针对公司财务管理的一点简单想法，只是路人甲的随便说说，不必当真。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一家软件公司一般是稳扎稳打的软件开发供应商，不具有投机性业务，财务政策应当稳健谨慎，应当保留足够多的现金储备，尤其在全球范围的金融风暴的肆虐下，现金为王，更应当视现金为过冬的基本生存资料。目前无法判断金融危机何时过去，但将其视为漫长的冰河时期是一种保守但却保险的做法。此时节流成为非常紧迫的任务。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">《孙子兵法》曰：&#8220;日费千金，然后十万之师举矣&#8221;。公司现在发展到数百位员工，租用了主城区大面积的办公场所，对外辐射了多个办事处，每月上缴税收、员工工资、场所租金、行政开支等等多如牛毛，虽不至日费千金，但也消耗惊人，公司纵是日进斗金，也是处于一种不算稳定的平衡。在此善意的假设公司收入骤减，则不知公司现金储备能支持多久。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我最近做某国有企业的报表项目，经常听闻该企业的会计们抱怨今年亏损厉害，而坊间也说其资不抵债，但此时国资委却向其注资几十亿，因为它是国有企业。但普通公司是自负盈亏的民营企业，无依无靠，若公司资不抵债，谁会向公司注资？</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">可谓&#8220;钱者，公司之大事，生死之地，存亡之道，不可不察也&#8221;。现金是公司的血液，无论多么强壮的人，若失血过多，必死无疑，则是人体基本生理特征决定的。而对有一定规模的公司若没有足够多的现金也是凶多吉少，这是公司这种社会组织的基本特征所决定的。这种客观存在的事实规律是不受人的意志为转移的。因此现金对公司来说是如此的重要，即使公司资金雄厚，也不能浪费一分一厘，否则会出现千里长堤，毁于蚁穴的情况。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">财务管理部门兢兢业业的做着财务审批的工作，看管着公司的现金，成天和人斤斤计较，其工作没什么突出的，但却是公司的守护神，守着公司最后的底线，其隐含的权威是不容挑战的。因此建议公司领导在全公司范围内明确声明财务管理部门的地位。财务管理部门的职责范围不大，但在其职责范围之内应当是无敌的。这同时也对财务管理部门成员的责任感和忠诚度提出比较苛刻的要求，并对公司的整体的平衡及和谐带来一点的影响。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">人体的体温能最能反映人体的健康状态，生病基本上会导致体温升高。而公司的现金收支就是公司的体温，公司的运营出现问题会很快导致现金收支的异常，这是一种普遍规律。因此市场和财务战线是业界老总的两大发源地，因为财务高手可以通过财务数据来较快速的判断公司运营是否正常，可以熟练使用各种财务分析技术手段来精确定位公司运营问题的所在。财务人员随便做了个财务报表就能深刻揭示公司运营中的一些问题，让我感触颇深，可能是因为我个人的成本观念比较重，由此产生一些共鸣。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">我建议公司应当加强全体员工、尤其是一线员工的成本观念，所谓&#8220;不当家不知柴盐贵&#8221;，平时和他人交流中，若有人家里搞装修，则他能如数家珍的把装修材料的价格、质量和人工成本等等说得很详细，因为他是&#8220;当家人&#8221;。同理若员工在公司中有&#8220;当家&#8221;感，则比如有很强的成本观念，不过公司如何给员工带来&#8220;当家&#8221;感则有些超出我个人的思考能力了，恕不能提出建设性的意见。</span></p>
<img src="http://www.cnblogs.com/xdesigner/aggbug/1370273.html?type=1" width="1" height="1" alt=""/><p>评论: 0　<a href="http://www.cnblogs.com/xdesigner/archive/2009/01/06/1370273.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2009/01/06/1370273.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item><item><title>关于南京四校联合程序设计大赛</title><link>http://www.cnblogs.com/xdesigner/archive/2008/12/15/1355071.html</link><dc:creator>袁永福</dc:creator><author>袁永福</author><pubDate>Mon, 15 Dec 2008 00:57:00 GMT</pubDate><guid>http://www.cnblogs.com/xdesigner/archive/2008/12/15/1355071.html</guid><description><![CDATA[<p>阅读: 3522 评论: 21 作者: <a href="http://www.cnblogs.com/xdesigner/" target="_blank">袁永福</a> 发表于 2008-12-15 08:57 <a href="http://www.cnblogs.com/xdesigner/archive/2008/12/15/1355071.html" target="_blank">原文链接</a></p><p style="text-indent: 21pt"><span style="font-family: 宋体">近期南京的东南大学、南京大学、南京航空航天大学和南京理工大学的微软俱乐部联合举行了一个基于微软技术的程序设计大赛，</span>2008<span style="font-family: 宋体">年</span>12<span style="font-family: 宋体">月</span>14<span style="font-family: 宋体">号我应邀去东南大学的九龙湖校区参加了一个学生软件开发项目比赛的复赛当评委。开始接触了当代高校学生的软件作品，水平参差不齐，但感觉有点后生可畏。在此提提几个印象比较深的学生项目。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">首先是一个名为&#8220;</span>Cross Media Search Project<span style="font-family: 宋体">&#8221;的项目，用于图片匹配查找，使用了比较高深的图形处理算法，我对此没有研究，感觉是将图片马赛克后在进行像素二维数组模糊匹配，不过我这个理解可能是错误的。该项目据说是有两个博士生研究算法。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">另外一个是&#8220;口袋</span>*<span style="font-family: 宋体">讲座——校园讲座信息精准投放平台&#8221;，是一个基于</span>WindowsMobile<span style="font-family: 宋体">的网络应用，服务端维护一个校园讲座信息库，而客户端是一个运行</span>Windows Mobile<span style="font-family: 宋体">的智能手机，安装一个</span>C#<span style="font-family: 宋体">编写的客户端软件，该软件通过无线网络连接服务器，使用者可以事先设置一些过滤条件，然后客户端就可以提醒使用者有某某应当感兴趣的讲座可以参与。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">一个叫&#8220;</span>Web Seracher<span style="font-family: 宋体">&#8221;的客户端软件，类似</span>RSS<span style="font-family: 宋体">订阅器，平时龟缩在系统托盘中，它能定期收集指定网页中的具有某种关键字的超连接信息，若有某个新超链接出现则可以提醒使用者。该软件开发中使用了工厂设计模式，装饰者设计模式。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">&#8220;</span>OurClass<span style="font-family: 宋体">&#8221;项目是一个</span>WEB2.0<span style="font-family: 宋体">的应用，用于建立高校班级班级，它定义了一套</span>ASP.NET<span style="font-family: 宋体">控件库用于提供班级网站的常见操作，这里的班级分支是由学校官方定义的。该项目介绍者没有使用</span>PPT<span style="font-family: 宋体">，而是搞了一个颇有动感的</span>Flash<span style="font-family: 宋体">来作为</span>PPT<span style="font-family: 宋体">使用。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">&#8220;</span>CookEasy<span style="font-family: 宋体">&#8221;项目是一个介绍菜肴制作的软件，该软件维护了一个菜谱库，能按照口味、食材、做法三种方式来显示所有的菜谱，它具有一个菜肴制作向导，指导使用者按部就班的制作菜肴，每个步骤还可以有时间控制。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">&#8220;小财神&#8221;项目是一个叫&#8220;</span>1822<span style="font-family: 宋体">工作室&#8221;的搞得，据说是基于金蝶的中间件开发的，实现了一个学校、学生和家长三方共同使用的理财管理系统。软件用户界面做的不错，</span>PPT<span style="font-family: 宋体">也不错。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">&#8220;</span>3D<span style="font-family: 宋体">魔方&#8221;就是将使用</span>Direct3D<span style="font-family: 宋体">技术实现一个魔方游戏软件，使用了</span>X<span style="font-family: 宋体">格式网格文件。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">此外还有一些游戏开发框架，能实现&#8220;英雄无敌&#8221;或&#8220;超级玛丽&#8221;样式的游戏，具体怎么实现的就不清楚了，不过游戏剧情编得有点意思。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这些学生有的只是大学二年级，对比我当年大二的水平那是非常强悍。而且很多人制作了比较不错的演示</span>PPT<span style="font-family: 宋体">和软件演示录像，后生可畏啊。造成这种情况我估计有两个原因，一方面是微软将各种高级软件开发技术进行了非常人性化的包装，使得以前高难度的软件开发过程变得比较容易。另外一方面就是现代的学生的综合水平确实比起我当年高出不少，有些学生已经懂得使用</span>PPT<span style="font-family: 宋体">，软件使用过程录屏，演讲和回答问题也比较流利。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">此外我还观摩了&#8220;</span>AI-TANK<span style="font-family: 宋体">&#8221;的坦克射击游戏射击比赛，对战双方都在一个坦克射击游戏平台上开发脚本，定义了各自的射击策略和躲避策略，坦克可以发射不同威力的炮弹，若命中对方则自身能量上升，有点像魔兽中的吸血光环的效果。然后双方都有</span>3<span style="font-family: 宋体">个坦克开战。这些游戏开发策略我不是很懂，反正胜者为王嘛。不过比赛中出现了一些小意外，有选手不服造成一些肢体冲突，果然愤青。</span></p>
<span style="font-size: 10.5pt; font-family: 宋体">虽然现在很多人讨论当代大学生能力如何如何，但不可否认，对于大学生中的强者，其综合素质是不断提高的。</span>
 <img src="http://www.cnblogs.com/xdesigner/aggbug/1355071.html?type=1" width="1" height="1" alt=""/><p>评论: 21　<a href="http://www.cnblogs.com/xdesigner/archive/2008/12/15/1355071.html#pagedcomment" target="_blank">查看评论</a>　<a href="http://www.cnblogs.com/xdesigner/archive/2008/12/15/1355071.html#commentform" target="_blank">发表评论</a></p><hr/><p>最新新闻：<br/>· <a href="http://news.cnblogs.com/n/56861/" target="_blank">苹果放出iPad专用iPhone OS 3.2 SDK</a><span style="color:gray">(2010-02-10 18:05)</span><br/>· <a href="http://news.cnblogs.com/n/56859/" target="_blank">美调查公司称苹果iPad配件成本最低219美元</a><span style="color:gray">(2010-02-10 17:20)</span><br/>· <a href="http://news.cnblogs.com/n/56858/" target="_blank">摩尔庄园：儿童生意密码</a><span style="color:gray">(2010-02-10 17:15)</span><br/>· <a href="http://news.cnblogs.com/n/56857/" target="_blank">Facebook与美国在线合作 整合AIM动态功能</a><span style="color:gray">(2010-02-10 16:41)</span><br/>· <a href="http://news.cnblogs.com/n/56855/" target="_blank">NDepend 3.0已与Visual Studio集成</a><span style="color:gray">(2010-02-10 16:17)</span><br/></p><p>编辑推荐：<a href="http://news.cnblogs.com/news/tag/Buzz/" target="_blank">Google Buzz相关新闻</a><br/></p><p>网站导航：<a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/" target="_blank">个人主页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://home.cnblogs.com/group/" target="_blank">小组</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://kb.cnblogs.com" target="_blank">知识库</a></p>]]></description></item></channel></rss>