﻿<?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>BlogJava-飞艳小屋-文章分类-.net</title><link>http://www.blogjava.net/songfei/category/4997.html</link><description>程序--人生--哲学___________________欢迎艳儿的加入</description><language>zh-cn</language><lastBuildDate>Thu, 28 Jun 2007 22:20:43 GMT</lastBuildDate><pubDate>Thu, 28 Jun 2007 22:20:43 GMT</pubDate><ttl>60</ttl><item><title>.net下程序的暴力修改</title><link>http://www.blogjava.net/songfei/articles/126776.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 28 Jun 2007 04:53:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/126776.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/126776.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/126776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/126776.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/126776.html</trackback:ping><description><![CDATA[最近为了使单片机的通信扩展到Internet使用了Lantronix公司生产的XPort（串口—网络口数据转发模块），在使用它带的软件DeviceInstaller进行软件的配置的时候，发现安装完毕启动时出现异常，异常信息如下 <br><br>未处理的&#8220;System.NotSupportedException&#8221;类型的异常出现在 mscorlib.dll 中。 <br><br>其他信息: 区域性&#8220;zh-CHS&#8221;是非特定区域性。它不能用于格式化和分析，因此不能设置为线程的当前区域性。 <br><br>使用。Net反编译工具，打开主程序XTool.exe,找到主窗体，此软件没有綺过混淆，代码很清晰，在Form1种 <br>public Form1() <br>{ <br>CultureInfo info1; <br>Version version1; <br>string text1; <br>DialogResult result1; <br>DialogResult result2; <br>string text2; <br>string text3; <br>string[] array1; <br>int num1; <br>ListViewColumnSorter sorter1; <br>base..ctor(); <br>CultureInfo.CurrentCulture.ClearCachedData(); <br>info1 = CultureInfo.CurrentCulture; <br>if (info1.TwoLetterISOLanguageName == "zh") <br>{ <br>&nbsp;Thread.CurrentThread.CurrentCulture = new CultureInfo(info1.Parent.LCID);// //此部分出错 <br>Thread.CurrentThread.CurrentUICulture = new CultureInfo(info1.Parent.LCID);// <span class=Ppi468>dl.bitsCN.com网管软件下载</span> <br>&nbsp;} <br>this.InitializeComponent(); <br>&nbsp; <br>} <br>就是Thread.CurrentThread.CurrentCulture = new CultureInfo(info1.Parent.LCID);将new 的 <br>CultureInfo(info1.Parent.LCID)赋给Thread.CurrentThread.CurrentCulture，出现了异常，因此不能设置为线程的当前区域性的异常。可能是程序为了比较好的支持国际化，而这样写的带代码，看来有些多余。看来只要不让出错的语句运行即可，而这最好的实现方式就是修改比较条件。 <br><br>可以使用两种方法进行修改 <br>1．使用ildasm进行反汇编，得到中间代码，修改中间代码，然后重新编译即可。 <br>使用ildasm进行反汇编后得到一大堆代码，下面仅仅列出相关的 <br>// 相关的汇编代码 <br>.maxstack 6 <br>.locals (CultureInfo V_0, Version V_1, string V_2, Exception V_3, DialogResult V_4, DialogResult V_5, string V_6, string V_7, string[] V_8, int V_9, ListViewColumnSorter V_10) <br>.try L_0132 to L_014a catch object L_014a to L_014d <br>.try L_014d to L_0574 catch Exception L_0574 to L_0584 <br>.try L_0739 to L_0754 catch object L_0754 to L_0768 <br>L_0000: ldarg.0 <br>L_0001: call Form..ctor <br>L_0006: call CultureInfo.get_CurrentCulture <span class=Ppi468>bitsCN全力打造网管学习平台</span> <br>L_000b: callvirt CultureInfo.ClearCachedData <br>L_0010: call CultureInfo.get_CurrentCulture <br>L_0015: stloc.0 <br>L_0016: ldloc.0 <br>L_0017: callvirt CultureInfo.get_TwoLetterISOLanguageName <br>L_001c: ldstr "zh" ------------将此处的字符串改为aa <br><br><br>再使用ilasm 将修改后的相关代码进行编译得到新程序即可。重新编译后，生成的程序比訽来的小了（可能有部分资源没有编译进去），不知道什么訽因，但是没有发现影响使用的状况 <br><br>2．简单的处理方式，一般的.net程序中使用的常量字符串，在.net程序中都有相应的储存位置（存储格式为unicode 形式），所以使用WinHex打开程序，查找字符串zh，选中unicode项，发现文件中仅能搜索到一次，毫无疑问，就是他了，直接将字符串 <br>7A 00 68 00 改为其他的不同字节即可。存盘后，程序正常运行<br><br><br>小弟最近一直在做.net下串行通信方面的程序，.net下没有自带的串口控件，使用以前的com组件又不甘心，所以在网上找到了sax.net组件（破解）版本，使用的时候，比较满意，但是在使用的过程中，出现了 <br><br>System.ArgumentOutOfRangeException: 长度不能小于 0。 <br><br>参数名: newlength <br><br>&nbsp;at System.Text.StringBuilder.set_Length(Int32 value) <br><br>&nbsp;at Sax.Communications.SerialConnection.a(UInt32 A_0) <br><br>&nbsp;at Sax.Communications.SerialConnection.a(IntPtr A_0, c&amp; A_1) <br><br>&nbsp;at Sax.Communications.SerialConnection.get_Available() <br><br>&nbsp;at Sax.Communications.SerialConnection.b() <br><br>&nbsp; <br><br>异常 <br><br>尤其是使用ISP线与单片机通信的时候，几乎每次插拔ISP线都会出现异常。异常后，控件的串口数据监视线程退出以后再也不能收发数据，只能重新启动软件。綺过仔细调试，发现 <br>异常出现在插拔数据线的时候，有数据收到，产生了DataAvailable事件中 <br><br>private void serialConnection_DataAvailable(object sender, EventArgs e) //受到数据时的处理函数 <br>&nbsp; { <br>&nbsp;//在这之前出现了异常
<div class=Air240>dl.bitsCN.com网管软件下载</div>
<br>&nbsp;int length = serialConnection.Available; <br>// Debug.WriteLine(length.ToString()); <br>&nbsp;if(length&lt;=0) return; <br>&nbsp; <br>&nbsp;Byte[] buffer = new byte[length]; //输入缓冲区有多少数据？ <br>&nbsp;serialConnection.Read(buffer,0,length); <br>&nbsp; <br>&nbsp;//分析数据 <br>&nbsp;if( length &gt; 0 ) <br>&nbsp;{ <br>&nbsp; HandleDataReceive(buffer); <br>&nbsp;} <br>&nbsp; } <br><br><br>就是在发生事件之后，在int length = serialConnection.Available;之前发生了异常。根据VS.net <br>的提示信息，初步确定是在给一个StringBuilder对象builder设置其Length的时候，传入的参数&lt;0导 <br>致的。 <br><br>好了，使用.net的反编译工具Reflector（我用的版本4.0.18）打开控件,找到SerialConnection类；由于此控件綺过混淆，所以在反编译后出现了大量的比如a，或者b这样的看不出作者意图的函数名。不过没有关系，因为异常出现在serialConnection.Available附近，直接找到Available的实现代码 <br><br>public override int get_Available() <br><br>{ <br><br>&nbsp; z.c c1; <br><br>&nbsp; this.c(); <br><span class=Air240>dl.bitsCN.com网管软件下载</span> <br>&nbsp; c1 = new z.c(); <br><br>&nbsp; this.a(this.a, ref c1); <br><br>&nbsp; if (this.b != -1) <br><br>&nbsp; { <br><br>&nbsp; return ((int) (c1.b + 1)); <br><br>&nbsp; } <br><br>&nbsp; return ((int) c1.b); <br><br>} <br>&nbsp; <br><br>在里面寻找出错的函数 <br>找到this.a(this.a, ref c1);这个 <br><br>private string a(IntPtr A_0, ref z.c A_1) <br><br>{ <br><br>&nbsp; uint num1 = 0; <br><br>&nbsp; z.ClearCommError(A_0, ref num1, ref A_1); <br><br>&nbsp; if (num1 != 0) <br><br>&nbsp; { <br><br>&nbsp; return this.a(num1); <br><br>&nbsp; } <br><br>&nbsp; return null; <br><br>} <br>&nbsp; <br><br>有追踪到return this.a(num1); <br><br>private string a(uint A_0) <br><br>{ <br><br>&nbsp; StringBuilder builder1 = new StringBuilder("UART Error:", 60); <br><br>&nbsp; if (builder1.Length &lt;= 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_005F; <br><br>&nbsp; } <br><br>&nbsp; goto Label_00D0; <span class=Air240>bitsCN.com中国网管联盟</span> <br><br>Label_001B: <br><br>&nbsp; builder1 = builder1.Append(" Parity,"); <br><br>&nbsp; goto Label_00B1; <br><br>Label_002C: <br><br>&nbsp; builder1 = builder1.Append(" Receive Overflow,"); <br><br>&nbsp; goto Label_0069; <br><br>Label_003D: <br><br>&nbsp; builder1 = builder1.Append(" Framing,"); <br><br>&nbsp; goto Label_0095; <br><br>Label_004E: <br><br>&nbsp; builder1 = builder1.Append(" Transmit Overflow,"); <br><br>&nbsp; goto Label_00A3; <br><br>Label_005F: <br><br>&nbsp; if ((A_0 &amp; 8) == 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_0095; <br><br>&nbsp; } <br><br>&nbsp; goto Label_003D; <br><br>Label_0069: <br><br>&nbsp; if ((A_0 &amp; 4) == 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_00B1; <br><br>&nbsp; } <br><br>&nbsp; goto Label_001B; <br><br>Label_0073: <br><br>&nbsp; builder1 = builder1.Append(" &lt;Unknown&gt;,"); <br><br>&nbsp; goto Label_00FA; <font color=#ffffff>bbs.bitsCN.com国内最早的网管论坛</font> <br><br>Label_0084: <br><br>&nbsp; builder1 = builder1.Append(" Overrun,"); <br><br>&nbsp; goto Label_00ED; <br><br>Label_0095: <br><br>&nbsp; if ((A_0 &amp; 1024) == 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_00E3; <br><br>&nbsp; } <br><br>&nbsp; goto Label_00BF; <br><br>Label_00A3: <br><br>&nbsp; if ((A_0 &amp; 1287) == 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_00FA; <br><br>&nbsp; } <br><br>&nbsp; goto Label_0073; <br><br>Label_00B1: <br><br>&nbsp; if ((A_0 &amp; 256) == 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_00A3; <br><br>&nbsp; } <br><br>&nbsp; goto Label_004E; <br><br>Label_00BF: <br><br>&nbsp; builder1 = builder1.Append(" IO,"); <br><br>&nbsp; goto Label_00E3; <br><br>Label_00D0: <br><br>&nbsp; builder1.Remove(0, builder1.Length); <br><br>&nbsp; goto Label_005F; <br><br>Label_00E3: <br><br>&nbsp; if ((A_0 &amp; 2) != 0) <br><br>&nbsp; { <font color=#ffffff>bitsCN.com中国网管联盟</font> <br><br>&nbsp; goto Label_0084; <br><br>&nbsp; } <br><br>Label_00ED: <br><br>&nbsp; if ((A_0 &amp; 1) == 0) <br><br>&nbsp; { <br><br>&nbsp; goto Label_0069; <br><br>&nbsp; } <br><br>&nbsp; goto Label_002C; <br><br>Label_00FA: <br><br>&nbsp; builder1.Length -= 1;//!!!!!!!!!!!!!!!!!!错误的来源 <br><br>&nbsp; return builder1.ToString(); <br><br>} <br><br>我靠，也没有想细读为什么要将builder1.Length 减去1，节省内存，没有必要把？！！ <br>反正是这句出错了，将后builder1.Length 小于0了 <br><br>查看前面的代码，没有对builder1.Length 赋值的语句，看来将这句改掉就行了， <br><br>查看il代码， <br>最后的几句为 <br>L_00fa: ldloc.0 <br>L_00fb: ldloc.0 <br>L_00fc: callvirt StringBuilder.get_Length <br>L_0101: ldc.i4.1 //装载常数1--将此处改为装载常数0，即可 <br>L_0102: sub <br>L_0103: callvirt StringBuilder.set_Length <br>L_0108: ldloc.0 <br>L_0109: callvirt StringBuilder.ToString <br>L_010e: ret <br><br>查找il的汇编指令 <br>发现（格式指令 ---十六进制数） <br>ldloc.0 ----06 <font color=#ffffff>play.bitsCN.com累了吗玩一下吧</font> <br>ldloc.0 ----06 <br>callvirt StringBuilder.get_Length ---- 6F X X X X (X不知道具体的值，可以通过模糊匹配来确定要修改的指令在文件的位置) <br>ldc.i4.1 ---- 17 <br><br><br><br>sub ----59 <br>L_0103: callvirt---- StringBuilder.set_Length 6F X X X X <br>L_0108: ldloc.0---- 06 <br>L_0109: callvirt---- StringBuilder.ToString 6F X X X X <br>L_010e: ret ----28 <br><br><br>使用WinHEx打开文件，使用16进制搜索，对于上面的X 使用模糊匹配的訽则 <br>找到偏移0x34B0处，在0x34BD处的将0x17 改为0x16(IL指令ldc.i4.0 ，就是将Length-0等于不减) <br>存盘退出，将修改好的dll文件覆盖訽来的dll,运行软件，怎么插拔ISP线都没有问题出现了！ <br><br><br>参考资料 <br>Ｉｎｓｉｄｅ　Ｍｉｃｒｏｓｏｆｔ．ｎｅｔ　ＩＬ　Ａｓｓｅｓｍｂｌｅｒ <br><br><br><br>
<img src ="http://www.blogjava.net/songfei/aggbug/126776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-06-28 12:53 <a href="http://www.blogjava.net/songfei/articles/126776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>应同学之邀,破解一个软件,学习逆向工程,文章如下</title><link>http://www.blogjava.net/songfei/articles/126610.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Wed, 27 Jun 2007 07:55:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/126610.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/126610.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/126610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/126610.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/126610.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: [.NET][爆破]我的Microsoft Math 3.0激活之路            [标&nbsp; &nbsp; 题][原创][.NET][爆破]我的Microsoft Math 3.0激活之路[作&nbsp; &nbsp;者]快雪时晴，2007年6月16日[目&nbsp; &nbsp; 标]&nbsp; &nbsp; &nbsp; &nbsp; 在CNBeta看到一则新闻：Micr...&nbsp;&nbsp;<a href='http://www.blogjava.net/songfei/articles/126610.html'>阅读全文</a><img src ="http://www.blogjava.net/songfei/aggbug/126610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-06-27 15:55 <a href="http://www.blogjava.net/songfei/articles/126610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> C#基础全接触</title><link>http://www.blogjava.net/songfei/articles/93800.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Sun, 14 Jan 2007 12:18:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/93800.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/93800.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/93800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/93800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/93800.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a href="http://blog.csdn.net/njuyama/archive/2006/09/26/1288202.aspx">
						<img height="13" src="http://blog.csdn.net/images/zhuan.gif" width="15" border="0" /> C#基础全接触</a>
		</div>
		<br />
		<div class="postText">
				<font face="Courier New"> </font>
				<p>引用类型是类型安全的指针，它们的内存是分配在堆（保存指针地址）上的。<br />String、数组、类、接口和委托都是引用类型。<br />强制类型转换与as类型转换的区别：当类型转换非法时，强制类型转换将抛出一个System.InvalidCastException异常，<br />而as不会抛出异常，它返回一个null值。<br />用using创建别名：using console = System.Console;<br />访问限定符：<br />public  该成员可以被其他任何类访问<br />protected 该成员只能被其派生类访问<br />private  该成员只能被本类的其他成员访问<br />internal 该成员只能在当前编译单元的其他成员访问<br />带参数列表和返回值的Main方法：<br />class Test<br />{<br />  public static int Main(string[] args)<br />  {<br />    foreach (string arg in args)<br />    {<br />    ...<br />    }<br />  }<br />}<br />构造函数（constructor）包括实例构造函数和静态构造函数。<br />构造函数与类名相同，且不能有返回值。例：<br />class TestClass<br />{<br />  TestClass()  //实例构造函数：可以访问静态成员和实例成员，用于初始化实例成员<br />  {<br />  ...<br />  }</p>
				<p>  static TestClass() //静态构造函数：只能访问静态成员，用于初始化静态成员<br />  {<br />  ...<br />  }<br />}<br />类的静态成员属于类所有，不必生成实例就可以访问，它是在载入包含类的应用程序时创建的，<br />但静态方法不能访问类的实例变量和方法。通常，静态变量是在定义时就赋初始值的。<br />类的实例成员属于类的实例所有，不创建实例对象就无法对其进行访问，实例成员可以访问类的<br />静态成员和其它实例成员。<br />调用基类的析构函数：<br />class A<br />{<br />  public A()<br />  {<br />  ...<br />  }<br />}<br />class B<br />{<br />  public B(): base()  //调用基类的析构函数<br />  {<br />  ...<br />  }<br />}<br />常量：其值是在编译时设定的，必须是数值文字。默认状态下常量是静态的。例：<br />class A<br />{<br />  public const double pi = 3.1415;<br />}<br />常量是编译时就确定的值，只读字段是在运行才能确定的值。比如运行时才能确定的屏幕分辨率。<br />只读字段只能在类的析构函数中赋值。<br />静态只读字段：<br />class A<br />{<br />  public static readonly int ScreenWidth;  //静态只读字段<br />  static A()   //静态析构函数<br />  {<br />    ScreenWidth = 1024;  //在静态析构函数中初始化<br />  }<br />}<br />在类的继承中，类的析构函数是不会被继承的。<br />一个派生类只能从一个基类继承，不能同时从多个基类继承，但可以通过继承多个接口来<br />达到相同目的。实现多继承的唯一方法就是使用接口。例：<br />class MyFancyGrid: Control, ISerializable, IDataBound<br />{<br />...<br />}<br />密封类是不能继承的类，抽象类不能被定义为密封类，且密封类的私有成员不能用protected修饰，<br />只能用private。例：<br />sealed class A<br />{<br />...<br />}<br />关键字ref和out用于指定用引用方式传递方法的参数。<br />它们的区别是：ref参数必须初始化，而out参数不需要初始化。所以在方法处理代码依赖参数的<br />初始化值时使用ref，不依赖初始化值时使用out。<br />对out参数即使在传递前对其进行了初始化，其值也不会传递到方法处理函数内部。传递时系统<br />会将其设为未初始化。所以在方法内部必须对out参数进行初始化。<br />方法重载时，必须参数数目和参数类型其中之一不同，返回值不同不能作为重载。<br />C#不支持方法的默认值，只能通过方法重载来实现。例：<br />class A<br />{<br />  int Method(int a)<br />  {<br />  ...<br />  }</p>
				<p>  void Method(int a, int b) //参数数目不同<br />  {    //返回值不同不能作为重载<br />  ...<br />  }<br />}<br />params参数用于一个不定数目参数的方法，一般后面跟一个数组。例：<br />class A<br />{<br />  public void Method(params int[] i)<br />  {<br />  ...<br />  }<br />}<br />方法的覆盖：指派生类覆盖基类的同名方法，有二种方法<br />1）第一种是在派生类要覆盖的方法前面加new修饰，而基类不需要作任何改动。<br />这种方法的缺点是不能实现多态。例：<br />class A<br />{<br />  public void Method()  //无需任何修饰<br />  {<br />  ...<br />  }<br />}</p>
				<p>class B: A   //从基类继承<br />{<br />  new public void Method() //覆盖基类的同名方法<br />  {<br />  ...<br />  }<br />}</p>
				<p>class TestClass<br />{<br />  A Instance = new B();<br />  Instance.Method();  //这时将调用类A的Method方法，而不是类B的Method方法<br />}</p>
				<p>2）第二种是在派生类要覆盖的方法前面加override修饰，而基类的同名方法前面加virtual修饰。<br />这样就能实现多态，例：</p>
				<p>class A<br />{<br />  virtual public void Method()   //基类定义虚方法<br />  {      //虚拟方法不能定义为private，因为private成员对派生类是无法访问的<br />  ...<br />  }<br />}</p>
				<p>class B: A     //从基类继承<br />{<br />  override public void Method()   //派生类覆盖基类的同名虚方法<br />  {<br />  ...<br />  }<br />}</p>
				<p>class TestClass<br />{<br />  protected void Test()<br />  {<br />    A Instance = new B();   //定义一个实例，类型为基类，从派生类创建<br />      //派生类总是能够向上转换为其基类<br />    Instance.Method();    //将调用派生类B的Method方法，而不是基类的，这就是多态<br />  }<br />}</p>
				<p>说明：new修饰的方法覆盖不能实现多态的原因，是因为使用new时编译器只会实现早期绑定（early binding）。<br />即调用的方法在编译时就决定了：编译器看到Instance.Method()而Instance的类是A，就会调用类A的Method()方法。<br />override修饰的方法覆盖可以实现多态的原因，是因为实现了后期绑定（late binding）。<br />使用override时强制编译器在运行时根据类的真正类型正确调用相应的方法，而不是在编译时。<br />而基类的同名方法必须加virtual修饰。<br />类的静态方法可能通过 类名.静态方法名 这种格式来调用，不能使用 实例名.静态方法名 这种方法调用。<br />因为类的静态方法为类所有（是属于类本身的），而非实例所有（不是属于类的实例的）。<br />类的静态方法可以访问类的任何静态成员，但不能访问类的实例成员。<br />C#中类的变量称为字段。类的public变量称为类的公共字段。<br />类的属性由一个protected（也可以是private）字段和getter和setter方法构成：<br />class Address<br />{<br />  protected string zipCode; //protected字段，注意大小写<br />  public string ZipCode<br />  {<br />    get    //getter方法<br />    {<br />      return zipCode;<br />    }<br />    set    //setter方法<br />    {<br />      zipCode = value;  //被传递的值自动被在这个value变量中<br />    }<br />  };<br />}<br />只读属性是指省略setter方法的属性，只读属性只能读取，不能设置。<br />属性也可以用限定符virtual，override和abstract修饰，功能同其他类的方法。<br />属性有一个用处称为懒惰的初始化（lazy initialization）。即在需要类成员时才对它们进行<br />初始化。如果类中包含了很少被引用的成员，而这些成员的初始化又会花费大量的时候和系统<br />资源的话，懒惰的初始化就很有用了。<br />C#中数组对象共同的基类是System.Array。<br />将数组声明为类的一个成员时，声明数组与实例化数组必须分开，这是因为只能在运行时创建了<br />类的实例对象之后，才能实例化数组元素值。<br />声明：<br />int[] intArray;  //一维数组<br />int[,,] int3Array; //三维数组<br />初始化：<br />intArray = new int[3] {1,2,3};<br />int[,] int2Array = new int[2,3] {{1,2,3},{4,5,6}}; //声明时可以初始化<br />遍历：<br />1）一维数组<br />for (int i = 0; i &lt; intArray.Length; i++); //Array.Length返回数组所有元素的个数<br />foreach (int i in intArray);<br />for (int i = 0; i &lt; intArray.GetLength(0); i++);//Array.GetLength(0)返回数组第一维的个数<br />2）多维数组<br />for (int i = 0; i &lt; int3Array.GetLength(0); i++) //遍历三维数组<br />  for (int j = 0; j &lt; int3Array.GetLength(1); j++)<br />    for (int k = 0; k &lt; int3Array.GetLength(2); k++)<br />    {<br />    ...<br />    }<br />数组的维数就是该数组的秩（Rank）。Array.Rank可以返回数据的秩。<br />锯齿数组（jagged Array）是元素为数组的数组，例：<br />int[][] jaggedArray = new int[2][]; //包含二个元素，每个元素是个数组<br />jaggedArray[0] = new int[2];  //每个元素必须初始化<br />jaggedArray[1] = new int[3];<br />for (int i = 0; i &lt; jaggedArray.Length; i++) //遍历锯齿数组<br />  for (int j = 0; j &lt; jaggedArray[i].Length; j++)<br />  {<br />  ...<br />  }<br />类的属性称为智能字段，类的索引器称为智能数组。由于类本身作数组使用，所以用<br />this作索引器的名称，索引器有索引参数值。例：<br />using System;<br />using System.Collections;<br />class MyListBox<br />{<br />  protected ArrayList data = new ArrayList();<br />  public object this[int idx]  //this作索引器名称，idx是索引参数<br />  {<br />    get<br />    {<br />      if (idx &gt; -1 &amp;&amp; idx &lt; data.Count)<br />      {<br />        return data[idx];<br />      }<br />      else<br />      {<br />        return null;<br />      }<br />    }<br />    set<br />    {<br />      if (idx &gt; -1 &amp;&amp; idx &lt; data.Count)<br />      {<br />        data[idx] = value;<br />      }<br />      else if (idx = data.Count)<br />      {<br />        data.Add(value);<br />      }<br />      else<br />      {<br />        //抛出一个异常<br />      }<br />    }<br />  }<br />}<br />接口是二段不同代码之间约定，通过约定实现彼此之间的相互访问。<br />C#并不支持多继承，但通过接口可实现相同功能。<br />当在接口中指定了实现这个接口的类时，我们就称这个类“实现了该接口”或“从接口继承”。<br />一个接口基本上就是一个抽象类，这个抽象类中除了声明C#类的其他成员类型——例如属性、<br />事件和索引器之外，只声明了纯虚拟方法。<br />接口中可以包含方法、属性、索引器和事件——其中任何一种都不是在接口自身中来实现的。例：<br />interface IExampleInterface<br />{<br />  //property declaration<br />  int testProperty { get; }</p>
				<p>  //event declaration<br />  event testEvevnt Changed;</p>
				<p>  //mothed declaration<br />  function void testMothed();</p>
				<p>  //indexer declaration<br />  string this[int index] { get; set; }<br />}<br />说明：定义接口时，在方法、属性、事件和索引器所有这些接口成员都不能用public之类的访问限定符，<br />因为所有接口成员都是public类型的。<br />因为接口定义了一个约定，任何实现一个接口的类都必须定义那个接口中每一个成员，否则将编译失败。例：<br />using System;<br />public class FancyControl<br />{<br />  protected string data;<br />  public string Data<br />  {<br />    get {return this.data;}<br />    set {data = value;}<br />  }<br />}</p>
				<p>interface IValidate<br />{<br />  bool Validate(); //接口方法<br />}</p>
				<p>public class MyControl: FancyControl, IValidate<br />{<br />  public MyControl()<br />  {<br />    data = "my control data";<br />  }</p>
				<p>  public bool Validate()  //实现接口<br />  {<br />    if (data == "my control data")<br />      return true;<br />    else<br />      return false;<br />  }<br />}<br />class InterfaceApp<br />{<br />  MyControl myControl = new MyControl();<br />  <br />  IValidate val = (IValidate)myControl;  //可以将一个实现某接口的类，转换成该接口<br />  bool success = val.Validate();  //然后可调用该接口的方法<br />}<br />也可以用：<br />bool success = myControl.Validate();<br />这种方法来调用Validate方法，因为Validate在类MyControl中是被定义成public的，如果去除public，Validate方法被隐藏，<br />就不能用这种方法调用了，这样隐藏接口方法称为名字隐藏（name hiding）。<br />可以用：类实例 is 接口名 来判断某个类是否实现了某接口，例：<br />myControl is IValidate  //MyControl类的实例myControl是否实现了IValidate接口<br />当然，也可用as来作转换，根据转换结果是否为null来判断某个类是否实现了某接口，例：<br />IValidate val = myControl as IValidate;<br />if (null == val)<br />{<br />...  //没有实现IValidate接口<br />}<br />else<br />{<br />...  //实现了IValidate接口<br />}</p>
				<p>如果一个类从多个接口继承，而这些接口中如果定义的同名的方法，则实现接口的方法时，必须加接口名来区别，<br />写成 接口名.方法名。假设Test类从IDataStore和ISerializable二个接口继承，而这二个接口都有SaveData()方法，<br />实现SaveData()方法时必须写成：<br />class Test: ISerializable, IDataStore<br />{<br />  void ISerializable.SaveData()<br />  {<br />  ...<br />  }</p>
				<p>  void IDataStore.SaveData()<br />  {<br />  ...<br />  }<br />}</p>
				<p>如果一个类从多个接口继承，为了方便可以定义一个新的接口，这个接口继续多个接口，然后类直接从这个接口继承就<br />可以了，这个叫合并接口。例：<br />interface ISaveData: ISerializable, IDataStore<br />{  //不需要定义任何方法或成员，只是用作合并<br />}<br />class Test: ISaveData  //只要继承ISaveData就可以了<br />{<br />...<br />}<br />C# 操作符优先级（从高到低）<br />初级操作符 () x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked<br />一元操作符 + - | ~ ++x --x (T)x<br />乘除操作符 * / %<br />加减操作符 + -<br />位移操作符 &lt;&lt; &gt;&gt;<br />关系操作符 &lt; &gt; &lt;= &gt;= is<br />等于操作符 ==<br />逻辑与  &amp;<br />逻辑异或 ^<br />逻辑或  |<br />条件与  &amp;&amp;<br />条件或  ||<br />条件操作符 ?:<br />赋值操作符 = *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |=<br />所有的二元操作符除赋值符外都是左联合的，即从左到右计算。<br />typeof()运算符可以从一个类名得到一个System.Type对象，而从System.Object对象继承来的GetType()方法<br />则可从一个类实例来得到一个System.Type对象。例：<br />Type t1 = typeof(Apple); //Apple是一个类名<br />Apple apple = new Apple(); //apple是Apple类的一个实例<br />Type t2 = apple.GetType(); //t1与t2是相同的<br />通过反射得到一个类的所有成员和方法：<br />Type t = typeof(Apple);<br />string className = t.ToString(); //得到类名<br />MethodInfo[] methods = t.GetMethods(); //得到所有方法<br />foreach (MethodInfo method in methods)<br />{<br />//用method.ToString()得到方法名<br />}<br />MemberInfo[] members = t.GetMembers(); //得到所有成员<br />foreach (MemberInfo member in members)<br />{<br />//用member.ToString()得到成员名<br />}<br />sizeof()操作符用来计算值类型变量在内存中占用的字节数（Bytes），并且它只能在unsafe（非安全）<br />代码中使用。例：<br />static unsafe public void ShowSizes()<br />{<br />  int i, j;<br />  j = sizeof(short);<br />  j = sizeof(i);<br />}<br />尽可能使用复合赋值操作符，它比不用复合赋值操作符的效率高。<br />for语句的语法为：<br />for (initialization; Boolean-expression; step)<br />  embedded-statement<br />在initialization和step部份还可以使用逗号操作符，例：<br />for (int i = '0', j = 1; i &lt;= '\xFF'; i++, j++)<br />for (int i = 1, j = 1; i &lt; 1000; i += j, j = i - j) //输出斐波那契数列<br /> Console.Write("{0} ", i);<br />在switch语句中执行一个分支的代码后还想执行另一个分支的代码，可以用：<br />goto case 分支;<br />操作符重载是为了让程序更加自然，容易理解。想要为一个类重新定义一个操作符，使用以下语法：<br />public static 返回值 operator 操作符 (操作对象1[，操作对象2])<br />说明：<br />1)所有重载的操作符方法都必须定义为public和static<br />2)从技术上说返回值可以是任何类型，但通常是返回所定义方法使用的类型<br />3)操作对象的数目取决于重载是一元操作符还是二元操作符，一元操作符只要一个操作对象，二元操作符则需要二个。<br />4)不管重载是一元操作符还是二元操作符，第一个操作对象的类型都必须与返回值的类型一致；而对于二元操作符的第二个<br />操作对象的类型则可以是任何类型。<br />5)只有下列操作符可以被重载：<br />一元：+ - ! ~ ++ -- true false<br />二元：+ - * / % &amp; | ^ &lt;&lt; &gt;&gt; == != &gt; &lt; &gt;= &lt;=<br />赋值操作符（+=,-=,*-,/=,%=等等）无法被重载。<br />[]和()操作符也无法被重载。<br />6)操作符的优先级是无法改变的，运算优先级的规则是静态的。</p>
				<p>例：假设一个Invoice发票类由多个InvoiceDetailLine类（成员只有一个Double类型的Amount金额属性）组成，<br />我们重载+操作符，使之可以将InvoiceDetailLine类的内容（注意不是金额合计）加在一起。<br />class Invoice<br />{<br />  public ArrayList DetailLine;<br />  <br />  public Invoice   //类的析构函数<br />  {<br />    DetailLine = new ArrayList(); //ArrayList存放多个InvoiceDetailLine类的实例<br />  }</p>
				<p>  public static Invoice operator+ (Invoice Invoice1, Invoice Invoice2) //参数与返回值的类型一致<br />  {<br />    //Invoice1与Invoice2的内容合并<br />    Invoice ReturnInvoice = new Invoice();<br />    foreach(InvoiceDetailLine detailLine in Invoice1.DetailLines)<br />      ReturnInvoice.DetailLine.Add(detailLine);<br />    foreach(InvoiceDetailLine detailLine in Invoice2.DetailLines)<br />      ReturnInvoice.DetailLine.Add(detailLine);<br />    return ReturnInvoice;<br />  }<br />}</p>
				<p>class InvoiceAddApp  //调用示例<br />{<br />  public static void main()<br />  {<br />    Invoice i1 = new Invoice();<br />    for(int i = 0; i &lt; 3; i++)<br />      i1.DetailLine.Add(new InvoiceDetailLine(i + 1));</p>
				<p>    Invoice i2 = new Invoice();<br />    for(int i = 0; i &lt; 3; i++)<br />      i2.DetailLine.Add(new InvoiceDetailLine(i + 1));</p>
				<p>    Invoice summaryInvoice = i1 + i2;  //调用重载的操作符+方法<br />  }<br />}</p>
				<p>
						<br />自定义类型转换可以编写代码实际二个不同的类、结构体之间的转换。<br />语法：public static implicite/explicite operator 输出类型 (输入类型)<br />说明：<br />1)转换方法必须是静态的。<br />2)implicite表示隐式转换，explicite表示显式转换。<br />3)输入类型和输出类型其中之一必须与包含转换的类或结构体类型。即转换必须与本类相关。<br />例：<br />struct Celisus<br />{<br />  public float t;</p>
				<p>  public Celisus(float t)<br />  {<br />    this.t = t;   //this.t是结构体的字段,t是参数<br />  }</p>
				<p>  public static implicite operator Celisus(float t) //float=&gt;Celisus<br />  {<br />    return new Celisus(t);<br />  }</p>
				<p>  public static implicite operator float(Celisus c) //Celisus=&gt;float<br />  {<br />    return ((c.t - 32) / 9) * 5;<br />  }<br />}</p>
				<p>
						<br />代表的(delegate)目的与C++中的函数指针相同，代表不是在编译时被定义的，而是在运行时被定义的。<br />代表主要有二个用途：回调(Callback)和事件处理(event)<br />回调通常用于异步处理和自定义处理。例：<br />class DBManager<br />{<br />  static DBConnection[] activeConnections;<br />  //声明回调函数<br />  public void delegate EnumConnectionCallback(DBConnection connection);</p>
				<p>  public static void EnumConnections(EnumConnectionCallback callback)<br />  {<br />    foreach (DBConnection connection in activeConnections)<br />    {<br />      callback(connection);  //执行回调函数<br />    }<br />  }<br />}</p>
				<p>//调用<br />class DelegateApp<br />{<br />  public static void ActiveConncetionCallback(DBConnection connection) //处理函数<br />  {<br />  ...<br />  }</p>
				<p>  public void main()<br />  {<br />    //创建指向具体处理函数的代表实例（新建一个代表，让它指向具体的处理函数）<br />    DBManager.EmnuConnectionCallback myCallback = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);<br />    DBManager.EnumConnections(myCallback);<br />  }<br />}</p>
				<p>//使用静态代表，上面的调用改为<br />class DelegateApp<br />{<br />  //创建一个指向处理函数的静态代表<br />  public static DBManager.EmnuConnectionCallback myCallback<br />    = new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);<br />  public static void ActiveConncetionCallback(DBConnection connection)<br />  {<br />  ...<br />  }</p>
				<p>  public void main()<br />  {<br />    DBManager.EnumConnections(myCallback);<br />  }<br />}</p>
				<p>//在需要时才创建代表，上面的调用改为<br />class DelegateApp<br />{<br />  //将创建代表放在属性的getter方法中<br />  public static DBManager.EmnuConnectionCallback myCallback<br />  {<br />    get<br />    {<br />      retun new DBManager.EmnuConnectionCallback(ActiveConncetionCallback);<br />    }<br />  }<br />  public static void ActiveConncetionCallback(DBConnection connection)<br />  {<br />  ...<br />  }</p>
				<p>  public void main()<br />  {<br />    DelegateApp app = new DelegateApp(); //创建应用程序<br />    DBManager.EnumConnections(myCallback);<br />  }<br />}</p>
				<p>
						<br />可以将多个代表整合成单个代表，例：<br />class CompositeDelegateApp<br />{<br />  public static void LogEvent(Part part)<br />  {<br />  ...<br />  }</p>
				<p>  public static void EmailPurchasingMgr(Part part)<br />  {<br />  ...<br />  }</p>
				<p>  public static void Main()<br />  {<br />    //定义二个代表<br />    InventoryManager.OutOfStockExceptionMethod LogEventCallback<br />      = new InventoryManager.OutOfStockExceptionMethod(LogEvent);<br />    InventoryManager.OutOfStockExceptionMethod EmailPurchasingMgrCallback<br />      = new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr);<br />    //整合为一个代表，注意后加的代表先执行（这里是先执行LogEventCallback）<br />    InventoryManager.OutOfStockExceptionMethod onHandExceptionEventsCallback<br />      = EmailPurchasingMgrCallback + LogEventCallback;<br />    //调用代表<br />    InventoryManager mgr = new InventoryManager();<br />    mgr.ProcessInventory(onHandExceptionEventsCallback);<br />    //InventoryManager类的ProcessInventory方法的原型为：<br />    //public void ProcessInventory(OutOfStockExceptionMethod exception);<br />  }<br />}</p>
				<p>可以根据需要将多个代表自由地组合成单个代表，例：<br />class CompositeDelegateApp<br />{<br />  //代表指向的处理函数（三个代表三个函数）<br />  public static void LogEvent(Part part)<br />  {<br />  ...<br />  }</p>
				<p>  public static void EmailPurchasingMgr(Part part)<br />  {<br />  ...<br />  }</p>
				<p>  public static void EmailStoreMgr(Part part)<br />  {<br />  ...<br />  }</p>
				<p>  public static void Main()<br />  {<br />    //通过数组定义三个代表<br />    InventoryManager.OutOfStockExceptionMethod[] exceptionMethods<br />      = new InventoryManager.OutOfStockExceptionMethod[3];<br />    exceptionMethods[0] = new InventoryManager.OutOfStockExceptionMethod(LogEvent);<br />    exceptionMethods[1] = new InventoryManager.OutOfStockExceptionMethod(EmailPurchasingMgr);<br />    exceptionMethods[2] = new InventoryManager.OutOfStockExceptionMethod(EmailStoreMgr);</p>
				<p>    int location = 1;<br />    //再定义一个代表（用于组合成单代表）<br />    InventoryManager.OutOfStockExceptionMethod compositeDelegate;<br />    //根据需要组合<br />    if (location = 2)<br />    {<br />      compositeDelegate = exceptionMethods[0] + exceptionMethods[1];<br />    }<br />    else<br />    {<br />      compositeDelegate = exceptionMethods[0] + exceptionMethods[2];<br />    }<br />    //调用代表<br />    InventoryManager mgr = new InventoryManager();<br />    mgr.ProcessInventory(compositeDelegate);<br />  }<br />}<br />C#的事件遵循“发布——预订”的设计模式。在这种模式中，一个类公布能够出现的所有事件，<br />然后任何的类都可以预订这些事件。一旦事件产生，运行环境就负责通知每个订户事件已经发生了。<br />当代表作为事件的处理结果时（或者说定义具有代表的事件），定义的代表必须指向二个参数的方法：<br />一个参数是引发事件的对象（发布者），另一个是事件信息对象（这个对象必须从EventArgs类中派生）。<br />例：<br />using System;</p>
				<p>class InventoryChangeEventArgs: EventArgs //事件信息对象，从EventArgs类派生<br />{<br />... //假设定义二个public属性string Sku和int Change<br />}</p>
				<p>class InventoryManager    //事件的发布者<br />{<br />  //声明代表<br />  public delegate void InventoryChangeEventHander(object source, InventoryChangeEventArgs e);<br />  //发布事件，event关键字可将一个代表指向多个处理函数<br />  public event InventoryChangeEventHandler onInventoryChangeHander;<br />  <br />  public void UpdateInventory(string sku, int change)<br />  {<br />    if (change == 0)<br />      return;<br />    InventoryChangeEventArgs e = new InventoryChangeEventArgs(sku, change);<br />    //触发事件<br />    if (onInventoryChangeHandler != null) //如果有预订者就触发<br />      onInventoryChangeHandler(this, e); //执行代表指向的处理函数<br />  }<br />}</p>
				<p>class InventoryWatcher    //事件的预订者<br />{<br />  public InventoryWatcher(InventoryManager mgr) //mgr参数用于联结发布者<br />  {<br />    this.inventoryManager = mgr;<br />    //预订事件，用 += 调用多个处理函数<br />    mgr.onInventroyChangeHandler += new InventoryManager.InventoryChangeEventHandler(onInventoryChange);<br />    //事件处理函数<br />    void onInventroyChange(object source, InventroyChangeEventArgs e)<br />    {<br />    ...<br />    }</p>
				<p>    InventoryManager inventoryManager;<br />  }<br />}</p>
				<p>class EventsApp     //主程序<br />{<br />  public static void Main()<br />  {<br />    InventoryManager inventoryManager = new InventoryManager();<br />    InventoryWatcher inventoryWatcher = new InventoryWatcher(inventoryManager);</p>
				<p>    inventoryManager.UpdateInventory("111 006 116", -2);<br />    inventoryManager.UpdateInventory("111 006 116", 5);<br />  }<br />}</p>
				<p>
						<br />Microsoft Windows NT和IBM OS/2等操作系统都支持占先型多任务。在占先型多任务执行中，处理器负责<br />给每个线程分配一定量的运行时间——一个时间片(timeslice)。处理器接着在不同的线程之间进行切换，<br />执行相应的处理。在单处理器的计算机上，并不能真正实现多个线程的同时运行，除非运行在多个处理器<br />的计算机上。操作系统调度的多线程只是根据分配给每个线程时间片进行切换执行，感觉上就像同时执行。</p>
				<p>上下文切换(context switching)是线程运行的一部分，处理器使用一个硬件时间来判断一个指定线程的时间片<br />何时结束。当这个硬件计时器给出中断信号时，处理器把当前运行的线程所用的所有寄存器(registers)数据<br />存储到堆栈中。然后，处理器把堆栈里那些相同的寄存器信息存放到一种被称为“上下文结构”的数据结构中。<br />当处理器要切换回原来执行的线程时，它反向执行这个过程，利用与该线程相关的上下文结构，在寄存器里<br />重新恢复与这一线程相关的信息。这样的一个完整过程称为“上下文切换”。</p>
				<p>多线程允许应用程序把任务分割为多个线程，它们彼此之间可以独立地工作，最大限度地利用了处理器时间。</p>
				<p>using System;<br />using System.Threading;</p>
				<p>class SimpleThreadApp<br />{<br />  public static void WorkerThreadMethod() //线程的执行体<br />  {<br />  ...      //执行一些操作<br />  }</p>
				<p>  public static void Main()<br />  {<br />    //创建一个线程代表指向线程的执行体，ThreadStart是创建新线程必须用到的代表<br />    ThreadStart worker = new ThreadStart(WorkerThreadMethod);<br />    Thread t = new Thread(worker);  //用线程代表创建线程<br />    t.Start();     //执行线程<br />  }<br />}</p>
				<p>可以通过两种方式来得到一个Thread对象：一种是通过创建一个新线程来得到，如上例；另一种在正在执行的线程调用<br />静态的Thread.CurrentThread方法。<br />静态方法Thread.Sleep(int ms)可以让当前线程（它自动调用Thread.CurrentThread）暂停指定毫秒的时间。<br />如果使用Thread.Sleep(0)那么当前线程将一直处于等待中，直到另一个线程调用这个线程的实例方法Thread.Interrupt方法，<br />等待才会结束。<br />使用Thread.Suspend方法也能挂起线程，Thread.Suspend方法可以被当前线程或其他线程调用，而Thread.Sleep(0)<br />只能由当前线程在执行体中调用。当线程用Thread.Suspend挂起时，必须用Thread.Resume方法恢复。不论Thread.Suspend<br />方法调用了多少次，只要调用Thread.Resume方法一次就可以线程恢复执行。用Thread.Suspend方法并不会阻塞线程，<br />调用立即返回。而Thread.Sleep(0)则会阻塞线程。所以确切地说Thread.Sleep(0)暂停线程，而不是挂起线程。<br />使用Thread.Abort方法可以终止正在执行的线程。当Thread.Abort方法被调用时，线程不会立即终止执行。运行环境将会<br />等待，直到线程到达文档中所描述的“安全点”。如果要确保线程已经完全停止，可以使用Thread.Join方法。这是一个同步<br />调用，同步调用意味着直到线程完全停止，调用才会返回。<br />Thread.Priority属性用于设置的线程的优先级。其值是Thread.ThreadPriority枚举值，可以设为Highest, AboveNormal,<br />Normal, BelowNormal, Lowest。缺省值是Thread.ThreadPriority.Normal。<br />线程的同步是为了解决多个线程同时使用同一对象产生的一些问题。通过同步，可以指定代码的临界区(critical section)，<br />一次只有一个线程可以进入临界区。<br />使用System.Monitor类（锁定与信号量）进行线程同步：<br />using System;<br />using System.Threading;</p>
				<p>public void SaveData(string text) //线程执行函数或线程执行函数调用的对象的方法<br />{<br />  ...   //执行其他一些不需要同步的处理</p>
				<p>  Monitor.Enter(this); //获取对象的Monitor锁<br />  ...   //执行需要同步的处理<br />  Monitor.Exit(this); //释放对象的Monitor锁</p>
				<p>  ...   //执行其他一些不需要同步的处理<br />}<br />说明：当执行Monitor.Enter方法时。这个方法会试图获取对象上的Monitor锁，如果另一个线程已经拥有了<br />这个锁，这个方法将会阻塞(block)，直到这个锁被释放。<br />也可用C#的lock语句来获得和释放一个Monitor锁。上面同步写成：<br />public void SaveData(string text) //线程执行函数或线程执行函数调用的对象的方法<br />{<br />  ...   //执行其他一些不需要同步的处理</p>
				<p>  lock(this)  //获取对象的Monitor锁，代码块执行完成后释放Monitor锁<br />  {<br />  ...   //执行需要同步的处理<br />  }</p>
				<p>  ...   //执行其他一些不需要同步的处理<br />}</p>
				<p>也可以使用System.Threading名称空间的Mutex类（互斥类）进行线程同步。与Monitor锁一样，一次只有一个线程<br />能获得一个给定的互斥。但Mutex要慢得多，但它增加了灵活性。例：<br />using System;<br />using System.Threading;<br />class Database<br />{<br />  Mutex mutex = new Mutex(false); //创建一个互斥，但不立即获得它<br />     //注意：创建互斥在需要同步的方法之外，实际上它只要创建一个实例<br />  public void SaveData(string text) //需要同步的方法<br />  {<br />    mutex.WaitOne();  //等待获得互斥<br />    ...    //需要同步的处理<br />    mntex.Close();  //释放互斥<br />  }<br />}</p>
				<p>Mutex类重载了三个构造函数：<br />Mutex()       //创建并使创建类立即获得互斥<br />Mutex(bool initiallyOwned)    //创建时可指定是否要立即获得互斥<br />Mutex(bool initiallyOwned, string muterName)  //还可以指定互斥的名称<br />Mutex.WaitOne方法也重载了三次：<br />Mutex.WaitOne()      //一直等待<br />Mutex.WaitOne(TimeSpan time, bool exitContext)  //等待TimeSpan指定的时间<br />Mutex.WaitOne(int milliseconds, bool exitContext) //等待指定的毫秒<br />线程的用法：<br />1)并发操作：比如一个程序监视多个COM口，当每个COM接到信息时执行一段处理时。<br />2)复杂长时间操作：一个长时间的复杂操作可能会使界面停滞，停止用户响应，如果还允许用户停止它，<br />或者显示进度条、显示操作执行进程信息时。<br />反射(Reflection)就是能够在运行时查找类型信息，这是因为.NET编译的可执行(PE)文件中包括MSIL和元数据(metadata)。<br />反射的中心是类System.Type。System.Type是一个抽象类，代表公用类型系统(Common Type System, CTS)中的一种类型。<br />using System;<br />using System.Reflection; //反射命名空间，必须引用</p>
				<p>public static void Main(string[] args)<br />{<br />  int i = 6;<br />  Type t = i.GetType();   //根据实例得到类型<br />  t = Type.GetType("System.Int32"); //根据类型的字符名称得到类型<br />}</p>
				<p>通过Assembly类可以得到已经编译.NET Framework程序的中所有类型，例：<br />using System;<br />using System.Diagnostics;  //为了使用Process类<br />using System.Reflection;  //为了使用Assembly类</p>
				<p>class GetTypesApp<br />{<br />  protected static string GetAssemblyName(string[] args)<br />  {<br />    string assemblyName;<br />    if (0 == args.Length) //如果参数为空，取当前进程的名称<br />    {<br />      Process p = Process.GetCurrentProcess();<br />      assemblyName = p.ProcessName + ".exe";<br />    }<br />    else<br />      assemblyName = args[0]; //取第一个参数，即当前运行程序名</p>
				<p>    return assemblyName;<br />  }</p>
				<p>  public static void Main(string[] args)<br />  {<br />    string assemblyName = GetAssemblyName(args);<br />    Assembly a = Assembly.LoadFrom(assemblyName); //调用编译程序集<br />    Type[] types = a.GetTypes();   //得到多个类型<br />    foreach (Type t in types)    //遍历类型数组<br />    {<br />    ...  //取得t.FullName,t.BaseType.FullName等类型信息<br />    }<br />  }<br />}<br />一个应用程序可以包括多个代码模块。若要将一个cs文件编译一个模块，只要执行下面的命令：<br />csc /target:module 要编译的模块.cs  //csc是C Sharp Compiler(C#编译器)<br />然后在应用程序中using编译的模块.cs中的NameSpace即可应用了。<br />要反射应用程序中所有代码模块(Module)，只要：<br />Assembly a = Assembly.LoadFrom(assemblyName); //应用程序的物理文件名<br />Module[] modules = a.GetModules();<br />foreach(Module m in modules)<br />{<br />... //显示m.Name等<br />}<br />后期绑定(latebinding),例：<br />string[] fileNames = Directory.GetFiles(Environment.CurrentDirectory, "*.dll");<br />foreach (string fileName in fileNames)<br />{<br />  Assembly a = Assembly.LoadFrom(fileName);<br />  Type[] types = a.GetTypes();<br />  foreach(Type t in types)<br />  {<br />    if (t.IsSubclassOf(typeof(CommProtocol)))  //判断是否有CommProtocol的派生类<br />    {<br />      object o = Activator.CreateInstance(t);  //生成实例<br />      MethodInfo mi = t.GetMethod("DisplayName");<br />      mi.Invoke(o, null);    //调用方法<br />    }<br />  }<br />}<br />//带参数的例子<br />namespace Programming_CSharp<br />{<br />  using System;<br />  using System.Reflection;<br /> <br />  public class Tester<br />  {<br />    public static void Main( )<br />    {<br />      Type t = Type.GetType("System.Math");<br />      Object o = Activator.CreateInstance(t);</p>
				<p>      // 定义参数类型<br />      Type[] paramTypes = new Type[1];<br />      paramTypes[0]= Type.GetType("System.Double");</p>
				<p>      MethodInfo CosineInfo = t.GetMethod("Cos", paramTypes);</p>
				<p>      //设置参数数据<br />      Object[] parameters = new Object[1];<br />      parameters[0] = 45;</p>
				<p>      //执行方法<br />      Object returnVal = CosineInfo.Invoke(o, parameters);<br />      Console.WriteLine("The cosine of a 45 degree angle {0}", returnVal);<br />    }<br />  }<br />}<br />动态生成代码和动态调用的完整例子：<br />//动态生成代码的部分<br />using System;<br />using System.Reflection;<br />using System.Reflection.Emit;  //动态生成代码必须引用</p>
				<p>namespace ILGenServer<br />{<br />  public class CodeGenerator<br />  {<br />    public CodeGenerator()<br />    {<br />      currentDomain = AppDomain.CurrentDomain;  //得到当前域<br />      assemblyName = new AssemblyName();  //从域创建一个程序集<br />      assemblyName.Name = "TempAssembly";<br />      //得到一个动态编译生成器，AssemblyBuilerAccess.Run表示只在内存中运行，不能保存<br />      assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilerAccess.Run);<br />      //从编译生成器得到一个模块生成器<br />      moduleBuilder = assemblyBuilder.DefineDynamicModule("TempModule");<br />      //模块生成器得到类生成器<br />      typeBuilder = moduleBuilder.DefineType("TempClass", TypeAttributes.Public);<br />      //为类添加一个方法<br />      methodBuilder = typeBuilder.DefineMethod("HelloWord", MethodAttributes.Public, null, null);<br />      //为方法写入代码，生成代码必须使用到IL生成器<br />      msil = methodBuilder.GetILGenerator();<br />      msil.EmitWriteLine("Hello World");<br />      msil.Emit(OpCodes.Ret);<br />      //最后还需要编译(build)一下类<br />      t = typeBuilder.CreateType();<br />    }<br />    AppDomain currentDomain;<br />    AssemblyName assemblyName;<br />    AssemblyBuilder assemblyBuilder;<br />    ModuleBuilder moduleBuilder;<br />    TypeBuilder typeBuilder;<br />    MethodBuilder methodBuilder;<br />    ILGenerator msil;<br />    object o;<br />    Type t;<br />    public Type T<br />    {<br />      get<br />      {<br />        return this.t;<br />      }<br />    }<br />  }<br />}<br />//动态调用的部分<br />using System;<br />using System.Reflection;<br />using ILGenServer;  //引用动态生成代码的类<br />public class ILGenClientApp<br />{<br />  public static void Main(<br />  {<br />    CodeGenerator gen = new CodeGenerator(); //创建动态生成类<br />    Type t = gen.T;<br />    if (null != t)<br />    {<br />      object o = Activator.CreateInstance(t);<br />      MethodInfo helloWorld = t.GetMethod("HelloWorld"); //为调用方法创建一个MethodInfo<br />      if (null != helloWorld)<br />      {<br />        helloWorld.Invoke(o, null);  //调用方法<br />      }<br />    }<br />  }<br />}<br />调用DLL<br />using System;<br />using System.Runtime.InteropServices; //为了使用DLLImport特性</p>
				<p>class PInvokeApp<br />{<br />  [DllImport("user32.dll", CharSet=CharSet.Ansi)] //CharSet.Ansi指定Ansi版本的函数(MessageBoxA),CharSet.Unicode指定Unicode版本的函数 (MessageBoxW)<br />  static extern int MessageBox(int hWnd, string msg, string caption, int type);  //声明DLL中的函数<br />  <br />  //[DllImport("user32.dll", EntryPoint="MessageBoxA")] //用这种方法使用不同的函数名<br />  //static extern int MsgBox(int hWnd, string msg, string caption, int type);<br />  <br />  //[DllImport("user32.dll", CharSet=CharSet.Unicode)]  //调用Unicode版的DLL函数<br />  //static extern int MessageBox(int hWnd, [MarshalAs(UnmanagedType.LPWStr)]string msg,<br />  // [MarshalAs(UnmanagedType.LPWStr)]string caption, int type); //将LPWStr翻译为string型，缺省情况系统只将LPStr翻译成string<br />  public static void Main()<br />  {<br />    MessageBox(0, "Hello, World!", "CaptionString", 0);  //调用DLL中的函数<br />  }<br />}<br />例2，使用回调：<br />class CallbackApp<br />{<br />  [DllImport("user32.dll")]<br />  static extern int GetWindowText(int hWnd, StringBuilder text, int count);</p>
				<p>  delegate bool CallbackDef(int hWnd, int lParam);</p>
				<p>  [DllImport("user32.dll")]<br />  static extern int EnumWindows(CallbackDef callback, int lParam);</p>
				<p>  static bool PrintWindow(int hWnd, int lParam)<br />  {<br />    StringBuilder text = new StringBuilder(255);<br />    GetWindowText(hWnd, text, 255);<br />    Console.WriteLine("Window Caption: {0}", text);<br />    return true;<br />  }</p>
				<p>  static void Main()<br />  {<br />    CallbackDef callback = new CallbackDef(PrintWindow);<br />    EnumWindows(callback, 0);<br />  }<br />}<br />关键字unsafe指定标记块在非控环境中运行。该关键字可以用于所有的方法，包括构造函数和属性，<br />甚至还有方法中的代码块。关键字fixed负责受控对象的固定(pinning)。Pinning是一种动作，向<br />垃圾收集器(Garbage Collector, GC)指定一些不能被移动的对象。为了不在内存中产生碎片，.NET<br />运行环境把对象四处移动，以便于最有效地利用内存。使用fixed后指定对象将不会被移动，所以就<br />可以用指针来访问它。<br />C#中只能得到值类型、数组和字符串的指针。在数组的情况下，第一个元素必须是值类型，因为C#<br />实际上是返回一个指向数组第一个元素的指针，而不是返回数组自身。<br />&amp; 取一个变量的内存地址（即指向该变量的指针）<br />* 取指针所指变量的值<br />-&gt; 取成员<br />例：<br />using System;<br />class UnsafeApp<br />{<br />  public static unsafe void GetValues(int* x, int* y)<br />  {<br />    *x = 6;<br />    *y = 42;<br />  }</p>
				<p>  public static unsafe void Main()<br />  {<br />    int a = 1;<br />    int b = 2;<br />    GetValues(&amp;a, &amp;b);<br />  }<br />}<br />fixed语法为：fixed(type* ptr = expression) statements<br />其中type也可以为非控类型，也可是void；expression是任何产生一个type指针的表达式；<br />statements是应用的代码块。例：<br />fixed (int* f = &amp;foo.x)  //foo是Foo类的一个实例，x是Foo类的一个int属性<br />{<br />  SetFooValue(f);  //SetFooValue方法的定义为unsafe static void SetFooValue(int* x)<br />}<br />传统的COM组件可以通过互操作层(COM Interop)与.NET运行环境交互。互操作层处理在托管运行环境和非托管区域<br />中的COM组件操作之间传递所有的消息。<br />要使COM组件能在.NET环境中使用,必须为COM组件生成元数据。.NET运行环境用元数据层业判断类型信息。在运行时刻<br />使用类型信息，以便生成RCW(Runtime Callable Wrapper,运行时可调用包装)。当.NET应用程序与COM对象交互时，<br />RCW处理对COM对象的装载和调用。RCW还完成许多其他的工作，如管理对象标识、对象生存周期以及接口缓冲区。<br />对象生存周期管理十分关键，因为.NET GC把对象到处移动，并且当对象不再使用时，自动处理这些对象。RCW服务告诉<br />.NET，应用程序正与托管.NET组件交互，同时又使非托管COM组件“觉得”COM对象是被传统的COM客户端调用的。<br />为了为COM组件生成元数据包装，必须使用tlbimp.exe(TypeLib Importer)工具：<br />tlbimp some_COM.tlb /out:som_COM.dll</p>
		</div>
<img src ="http://www.blogjava.net/songfei/aggbug/93800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2007-01-14 20:18 <a href="http://www.blogjava.net/songfei/articles/93800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VB中的Unicode 和 Ansi 格式 转换</title><link>http://www.blogjava.net/songfei/articles/55780.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 29 Jun 2006 08:54:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/55780.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/55780.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/55780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/55780.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/55780.html</trackback:ping><description><![CDATA[VB中的Unicode 和 Ansi 格式 <br /><br />Visual Basic 32-bit 版本的字串处理采用 Unicode，也就是说字串在 VB 内部是以Unicode 的格式来存放。何谓 Unicode？简单的说，就是每一个字符都是以 2-byte 的形式表示，而每个「实体字符」就是一个「字符」。因此，<br /><br />Len("大家好")<br /><br />Len("abc")<br /><br />所返回的值都是 3，因为「大」和「a」都是一个字符。<br /><br /><br />但是这对一些中文字串处理，例如纯文字的数据文件，却是一个大灾难，因为你必须以byte 来定位每个字符，可是 Unicode 却把一切的处理全搞砸了。例如：<br /><br />Len("Good Morning") 返回 12，而<br /><br />Len("今天天气很好") 返回 6<br /><br /><br />对初学者而言，好不容易能使用 VB 来写程序已经是件了不起的事了，却马上在中文处理上挨了一记闷棍，所受到的打击实在不小。但是不要怕，事实上只要再多了解一些指令，就可以把中文处理的问题解决了。<br /><br /><br />是什么指令呢？最重要的莫过于 StrConv 了。StrConv 函数的语法为：StrConv(待转换字串, 转换格式)<br /><br />其中转换格式在这里用到的是：<br /><br />vbUnicode 将 Ansi 字串转换为 Unicode<br /><br />vbFromUnicode 将 Unicode 字串转换为 Ansi<br /><br />将字串转成 Ansi 之后，所有的字串处理指令都要加个 B，例如：LeftB, RightB,<br /><br />MidB, ChrB, InstrB, LenB, InputB 等。例用这些指令来处理就行了。<br /><br /><br />当你处理完毕之后，你可以再将它再转回 Unicode，这样就可以使用一般的字串处理指令了。这样讲看得懂吗？如果还是不了解，看看下面的实例说明：<br /><br />简易使用范例<br /><br />看看下面的基本范例您应该就会对 VB 的字串处理方式有些概念。<br /><br /><br />Private Sub Command1_Click ()<br /><br />Dim sUnicode As String<br /><br />Dim sAnsi As String<br /><br />' Unicode 运算<br /><br />sUnicode = "王小明,A123456789,651023,上海市中山路100号,(02)2345678"<br /><br />Debug.Print Len(sUnicode) ' 返回 44<br /><br />Debug.Print Mid$(sUnicode, 5, 10) ' 返回 A123456789<br /><br />Debug.Print Instr(sUnicode, "上海市") ' 返回 23<br /><br />' 将 Unicode 字串转成 Ansi<br /><br />sAnsi = StrConv(sUnicode, vbFromUnicode)<br /><br />' Ansi 运算<br /><br />Debug.Print LenB(sAnsi) ' 返回 54<br /><br />Debug.Print MidB$(sAnsi, 8, 10) ' 返回 ?????，因为忘了转回 Unicode<br /><br />Debug.Print StrConv(MidB$(sAnsi, 8, 10), vbUnicode) ' 返回 A123456789，请注意转回 Unicode 的动作一定要做<br /><br /><br />Debug.Print InStrB(sAnsi, StrConv("上海市", vbFromUnicode)) ' 返回 23, 不要忘了要把"上海市"也转成 Ansi，否则会找不到<br /><br />End Sub<br /><br />读入文本文件<br /><br />在 VB 的小技巧中，有一个是快速读文件法：<br /><br />Private Sub Command1_Click ()<br /><br />Dim sFile As String<br /><br />Open "C:\filename.txt" For Input As #1<br /><br />sFile = Input$(LOF(1), #1)<br /><br />Close #1<br /><br />End Sub<br /><br /><br />但是很不幸地，如果你读取的文件内含中文字，那上面这段程序会出现 Input pastend of file 的错误。因为 LOF 返回的是文件的 byte 数，而 Input 函数读取的是字符数，由于文件内含中文，因此文件中的字符数将会小于 byte 数，于是就发生错误了。要解决这个问题，我们就要用到 StrConv 和 InputB 这两个函数了：<br /><br />Private Sub Command1_Click ()<br /><br />Dim sFile As String<br /><br />Open "C:\filename.txt" For Input As #1<br /><br />sFile = StrConv(InputB$(LOF(1), #1), vbUnicode)<br /><br />Close #1<br /><br />End Sub<br /><br />上面修正程序先用 InputB 将文件读进来，不过使用 InputB 所读入的文件是 Ansi格式的，所以要再用 StrConv 转成 Unicode 才行。随机数据文件许多文字数据文件是以固定字节的位置来加以区格，例如下面的数据格式：王小民650110上海市中山路100号 (02)1234567<br /><br />张大呆660824花莲县大甲镇广东街23号(03)9876543<br /><br /><br />像这种类型的文件要如何处理呢？这是就必须用到 Type 以及 byte array 了。<br /><br />Private Type tagRecord<br /><br />Username(5) As Byte ' 姓名 6 bytes<br /><br />Birthday(5) As Byte ' 生日 6 bytes<br /><br />Address(21) As Byte ' 地址 22 bytes<br /><br />TEL(11) As Byte ' 电话 12 bytes<br /><br />CrLf(1) As Byte ' 换行字符 2 bytes<br /><br />End Type<br /><br /><br />Private Sub Command1_Click()<br /><br />Dim uRecord As tagRecord<br /><br />Open "C:\filename.dat" For Random As #1 Len = LenB(uRecord)<br /><br />Get #1, 2, uRecord ' 取第二笔数据<br /><br />With uRecord ' With ... End With 应该会用吧<br /><br />Debug.Print .Username ' 返回 ???<br /><br />Debug.Print StrConv(.Username, vbUnicode) ' 返回 "张大呆"<br /><br />End With<br /><br />Close #1<br /><br />End Sub<br /><br /><br />在这个例子中，一定要用到 byte array，因为只有 byte array 才能正确地定位到每个 byte 的位置。以前使用字串来定位的方法已经不适用了，千万要记住！但是使用byte array 所读入的数据是 Ansi 格式，若要处理或是做运算的话，记得还要转成Unicode 格式才行。<br /><br /><br />[●] 使用 Byte Array<br /><br />除了上面必须使用 byte 精确定位的例子之外，纯文字的处理基本上是用不到 bytearray 的。byte array 通常是用在处理 binary 数据。这方面的问题我们将另文讨论。看吧！只要熟悉使用 StrConv，你就可以在 Unicode 及 Ansi 格式之间自由自在地变来变去，相信当您看完这篇文章之后，对处理中文应该不再烦恼了吧！<br /><br /><img src ="http://www.blogjava.net/songfei/aggbug/55780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2006-06-29 16:54 <a href="http://www.blogjava.net/songfei/articles/55780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从VB 6到VB.NET——窗体特殊应用</title><link>http://www.blogjava.net/songfei/articles/55748.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 29 Jun 2006 06:49:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/55748.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/55748.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/55748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/55748.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/55748.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 从VB 6到VB.NET——窗体特殊应用李洪根一、   摘要    VB .NET做为VB6的升级版本，具备了许多新的功能，它可以简便快捷地创建 .NET 应用程序（包括 XML Web services 和 ASP.NET Web 应用程序），还是一个功能强大的面向对象的编程语言（如继承、接口和重载）。新的语言功能包括自由线程处理和结构化异常处理。VB.NET 还完全集成了.NET 框架和公共语...&nbsp;&nbsp;<a href='http://www.blogjava.net/songfei/articles/55748.html'>阅读全文</a><img src ="http://www.blogjava.net/songfei/aggbug/55748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2006-06-29 14:49 <a href="http://www.blogjava.net/songfei/articles/55748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#与vb.net的区别 </title><link>http://www.blogjava.net/songfei/articles/50774.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Tue, 06 Jun 2006 07:17:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/50774.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/50774.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/50774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/50774.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/50774.html</trackback:ping><description><![CDATA[
		<p>都说在.NET里，.NET framework和CLR是应用运行的基础。那么VB.NET和C#是不是就完全一样，只是语法不同吗？</p>
		<p>一、C#</p>
		<p>--- 像VB一样简单，像C++一样强大的新语<br />C#是第一流的面向组件的语言<br />由 Turbo Pascal, Delphi, and Visual J++的首席设计师Anders Hejlsberg 倾心3年设计<br />所有的语言元素都是真正的对象<br />开发强壮和可重用的软件<br />所有的.NET Framework中的基类库（Base Class Library）都由C# 编写</p>
		<p>
				<br />二、VB.NET</p>
		<p>--- 完全面向对象的BASIC语言</p>
		<p>1.新语言特性<br />完全面向对象–  继承(Inheritance), 重载(overloading), 共享的成员, 结构化异常处理<br />强壮的语言 –  严格的类型检查, 变量声明时初始化，支持垃圾收集(Garbage collection)<br />强大 –  支持委托(Delegates), free threading，Variant 数据类型被 Object 代替<br />2.与VB6一致的语法</p>
		<p>三、2者的区别？<br />1.语法上的差异<br />        例如循环的写法</p>
		<p>VB.NET</p>
		<p>For I = 1 To 10<br />   ‘ for loop<br />Next I</p>
		<p>C#</p>
		<p>For (i=1;i&lt;11;i++) {<br />// for loop<br />}<br />另外Visual Basic 对大小写不敏感，而C#是大小写敏感的。</p>
		<p>2.C# 具有但 Visual Basic 不具有的特性<br />           指针, 移位操作符, 内嵌的文档(XML)<br />          重载操作符</p>
		<p>3.Visual Basic具有但 C# 不具有的特性</p>
		<p>更丰富的语法: Events, Try…Catch, Select…Case, 实现 Interface <br />后期绑定(Late binding), 动态数组, 模块(modules), 可选参数, 参数属性(parameterized properties)<br />后台编译</p>
		<p>
				<br />C#与VB.net间移植的技巧</p>
		<p>
				<br />按理说，这两种语言没有什么移植的必要，因为他们生成的代码可以完全通用。但是如果一个工程基本上是VB写成的，却需要少许已经存在的C#过程，用组件并不是一种效率很高的办法。就算是学习C#或VB，学会他们之间的移植可以双倍的利用已经存在的代码（如好玩的Donkey.net就只有VB版）。 <br />   <br />  有人比较过这两种语言，得出的结论是他们很相似。但即便是这样，VB初学者看到诸如(（Button）sender).Text = “启动”;之类的语法不知道如何移植到VB，而C#初学者看到Handles Button1.Click等语法也会为移植而感到头痛。下面就看看他们最难移植的部分： <br />   <br />  1、Option语句。VB的Option语句可以打开或关闭变量声明检查和类型转换检查。尤其是Option Strict被关闭后，VB变成弱类型语言，很多类型转换都是自动的，移植到C#中会产生无数错误。因此，如果要将带有Option Strict Off语句的VB程序移植到C#，最好先在VB中将Option Strict打开，然后把所有类型转换出错的地方变成强类型转换，然后再进行移植。 <br />   <br />  2、类型转换。VB提供了很多类型转换函数型运算符，如CInt(), CSng(), CStr()等，在C#中只要用(int) , (float), (String)即可。然而如果不是标准类型，如下面的C#语句： <br />   <br />  ((System.Button)sender).Text = “启动”; <br />   <br />  就要使用VB的函数型运算符CType来实现。上面的代码正确的移植方法是： <br />   <br />  CType(sender, System.Button).Text = “启动” <br />   <br />  千万不要使用某些人推荐的，将Option Strict关闭，然后用后期绑定调用sender对象的方法，这根本不符合程序移植不能改变本质的要求。 <br />   <br />  3、修饰符和属性标签。VB和C#的修饰符是完全对等存在的，但是拼写往往不同，给移植带来了很多麻烦，尤其是表示相同意思的关键字从字面理解完全不同的时候。下面就给出了VB和C#对应的关键字： <br />   <br />  VB <br />   C# <br />   VB <br />   C# <br />   <br />  Inherits <br />   : <br />   Implements <br />   : <br />   <br />  MustInherit <br />   abstract <br />   NotInheritable <br />   sealed <br />   <br />  Overridable <br />   virtual <br />   NotOverridable <br />   sealed <br />   <br />  MustOverride <br />   abstract <br />   Overrides <br />   override <br />   <br />  [Overloads] <br />   无 <br />   Shadows <br />   new <br />   <br />  Shared <br />   static <br />   Public <br />   public <br />   <br />  Protected <br />   protected <br />   Friend <br />   internal <br />   <br />  Protected Friend <br />   protected internal <br />   Private <br />   private <br />   <br />  Static <br />   用别的方法实现 <br />   ByVal <br />   无 <br />   <br />  ByRef <br />   ref <br />   Optional <br />   无 <br />   <br />  ParamArray <br />   params <br />   无法实现 <br />   unsafe <br />   <br />  无法实现 <br />   fixed <br />   <br />   <br />  可以看出，VB的关键字比较长，而且使用上也比C#更加严格。从C#向VB移植的时候，要分外注意哪些VB有而C#没有的关键字以及在C#拼写相同，在VB中拼写不同的关键字（如MustOverride和MustInherit）。有些关键字如unsafe，如果C#使用了他们，将无法移植到VB中。好在这些关键字在商业应用中并不常用。 <br />   <br />  属性标签在这两种语言中非常的相似，移植上应该没有任何难度，只要知道在C#中用方括号[]表示属性标签，而在VB中用的是尖括号&lt;&gt;。另外，如果要用名称结合传递参数，C#直接使用=号，而VB使用:=（冒号和等号）。 <br />   <br />  4、委派类型。委派类型就是安全的函数指针类型。在C#中，难以分辨是函数指针在工作还是函数本身在工作，因为他们的语法相同。当要为一个委派类型的变量复制的时候，直接等于一个函数即可，如： <br />   <br />  public delegate void FuncType(Object e) <br />   <br />  ... <br />   <br />  FuncType func; <br />   <br />  func = new FuncType(this.SampleFunction1); <br />   <br />  //调用 <br />   <br />  func(something); <br />   <br />  //换指向另外一个函数 <br />   <br />  func = this.SampleFunction2 <br />   <br />  然而VB中，委派类型就像是一般的对象，有它的方法，与函数本身明显不同。你不能将过程的名字直接赋给一个委派类型的对象，而必须使用AddressOf运算符，下面的例子就是上文C#程序的VB版，注意那些实现不同的地方： <br />   <br />  Public Delegate Sub FuncType(ByVal e As Object) <br />   <br />  ... <br />   <br />  Dim func As FuncType <br />   <br />  func = New FuncType(AddressOf Me.SampleFunc1) <br />   <br />  ‘ 调用 <br />   <br />  func.Invoke(something) <br />   <br />  ‘ 换指向另外一个函数 <br />   <br />  func = AddressOf Me.SampleFunction2 <br />   <br />  5、事件处理。这是两种语言最大的差别之一，VB传承以前版本强大的事件处理机制，许多语法都比C#更加灵活。好在无论什么情况，他们之间都是可以互相移植的。 <br />   <br />  对于事件定义，两种语言都是一个委派类型加一个事件属性，如： <br />   <br />  [C#] <br />   <br />  public delegate void MyEventHandler(Object sender, EventArgs e); <br />   <br />  public event MyEventHandler MyEvent; <br />   <br />  [Visual Basic] <br />   <br />  Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs) <br />   <br />  Public Event MyEvent As MyEventHandler <br />   <br />  VB还支持另外一种更加紧凑的定义方法，只有一条语句： <br />   <br />  Public Event MyEvent(ByVal sender As Object, ByVal e As EventArgs) <br />   <br />  移植的时候，要把参数部分分离出来，成为一个委派类型，再按照普通方法定义事件即可。 <br />   <br />  关于事件响应，C#与Delphi等语言一样，是动态绑定事件过程的，其语法类似于下： <br />   <br />  internal MyClass myobj; <br />   <br />  ... <br />   <br />  myobj = new MyClass(); <br />   <br />  ... <br />   <br />  myobj.MyEvent += this.myobj_MyEvent; <br />   <br />  ... <br />   <br />  protected void myobj_MyEvent(Object sender, EventArgs e) <br />   <br />  { <br />   <br />   //语句 <br />   <br />  } <br />   <br />  可以看到，C#是利用运算符连接事件过程和事件属性的。之后，还可以用-=运算符解除事件过程与事件属性的绑定。VB不支持运算符重载，但仍然支持这种动态绑定的事件过程，方法是使用AddHandler和RemoveHandler关键字。如上面黑体部分可以移植为： <br />   <br />  AddHandler myobj.MyEvent, AddressOf Me.myobj_MyEvent <br />   <br />  解除绑定的语法与此类似，只是关键字为RemoveHandler而已。一定不要忘记过程前面还有一个AddressOf关键字！ <br />   <br />  动态绑定的事件过程工作起来比较慢，VB支持一种更快的静态绑定事件过程。一旦为对象设置了静态的事件过程，就不能解除绑定，一般大多数情况都是如此。语法如下： <br />   <br />  ‘ 定义变量时使用WithEvents关键字 <br />   <br />  Friend WithEvents myobj As MyClass <br />   <br />  ‘ 直接书写事件过程，注意Handles的语法： <br />   <br />  Protected Sub myobj_MyEvent(ByVal sender As Object, ByVal e As EventArgs) _ <br />   <br />  Handles myobj.MyEvent <br />   <br />   ‘ 语句 <br />   <br />  End Sub <br />   <br />  它表示myobj_MyEvent这个过程仅仅响应myobj.MyEvent这个过程。如果一个过程要响应很多个事件，把他们列在Handles后面，用逗号隔开，如Handles Event1, Event2, ... <br />   <br />  遇到这种情况，要看清Handles后面的所有对象和事件，将它们一一改写成动态绑定的语句： <br />   <br />  Protected Sub XXX(...) Handles myobj1.MyEvent, myobj2.MyEvent <br />   <br />  ==&gt; <br />   <br />  myobj1.MyEvent += this.XXX; <br />   <br />  myobj2.MyEvent += this.XXX; <br />   <br />  ... <br />   <br />  protected void XXX(...){} <br />   <br />  当事件比较多时，C#显著变得比较麻烦，幸好一个过程响应一大堆事件的情况也不太多（不过我就编写过一个过程相应8个事件，移植起来好麻烦！）。原则上说，将静态事件过程移植为动态事件过程并没有完全遵守移植的规定，但我估计他们实现的原理不会相差太多，所以也不用担心。 <br />   <br />  6、异常处理。VB支持两种形式的异常，即.net框架的异常和VB自己的错误号码。而C#只支持第一种。用到VB自己的错误号码的程序几乎无法移植到C#中，所以应该尽量使用.net框架的异常，如下面VB语句： <br />   <br />  Try <br />   <br />   ‘ 发生错误的代码 <br />   <br />  Catch When Err.Number = 52 <br />   <br />   ‘ 解决错误的代码 <br />   <br />  End Try <br />   <br />  这段代码无法直接移植到C#中，只有用Exception对象取代Err对象获得异常信息，才能顺利移植。另外VB的When语句带给Try语句十分灵活的用法，必须用很高的技巧才能在C#中实现，这就需要具体问题具体分析了。 <br />   <br />  VB支持Exit Try语句，可以直接从Try块或Catch块跳转到Finally块。C#没有提供类似的语法，可以用以下技巧： <br />   <br />  [Visual Basic] <br />   <br />  Try <br />   <br />   ‘ 一些语句 <br />   <br />   Exit Try <br />   <br />  Finally <br />   <br />   ‘ 一些语句 <br />   <br />  End Try <br />   <br />  [C#] <br />   <br />  try <br />   <br />  { <br />   <br />   //一些语句 <br />   <br />   goto __leave; <br />   <br />  } <br />   <br />  finally <br />   <br />  { <br />   <br />   //一些语句 <br />   <br />  } <br />   <br />  __leave: //别忘了这里还有哦！ <br />   <br />  总之是利用了finally块无法跳过的特征，用goto语句模拟了Exit Try语句。 <br />   <br />  如果VB程序用的是VB特有的On Error GoTo语句实现的错误处理，问题就麻烦了。代码可能在过程中上下跳跃，无法预料语句的执行方式。这种代码理解起来就头痛，更不要说移植了。总体来说，把所有语句统统转移到try块中，然后用catch一一处理错误。遇到要返回（Resume语句）的时候，只好Copy代码了。反正不是一件容易的事情，慢慢改就是了。 <br />   <br />  7、模块。VB支持模块，C#不支持。但也没有关系，只要在C#中制造一个abstract类，共享所有成员，就和模块一样了。当然不能像VB一样直接访问模块中的成员，需要用到“类名.成员名”的用法。 <br />   <br />  8、接口。C#在接口方面也没有VB强大（怎么这么重要的功能也不做得好一点？），VB采用Implements语句结合接口的成员和类的实现成员，而C#是用名称结合。因此VB就可以随便修改实现成员的访问级别和名称，而C#就不能改名称。将C#移植为VB时，最好利用VB.net编辑器直接实现接口，比较简单。把VB移植为C#时，就必须把改过的名字都改回来，遇到名字冲突就更讨厌了（这时候我几乎不想再移植为C#了）。给一个例子： <br />   <br />  [Visual Basic] <br />   <br />  Public Class Class1 : Implements IMyInterface <br />   <br />   Public Sub DoSth() Implements IMyInterface.Method1 <br />   <br />   End Sub <br />   <br />  End Class <br />   <br />  [C#] <br />   <br />  public class Class1 : IMyInterface <br />   <br />  { <br />   <br />   public void Method1() <br />   <br />  { <br />   <br />  } <br />   <br />  } <br />   <br />  9、运算符重载。这会遇到VB头痛了，既然VB不支持运算符重载，那么就必须用子程序和函数来模拟运算符。比如建立Plus和Minus方法模拟+和-的运算。当然还是有很多情况（比如遇上了explicit和implicit语句）就真的没有办法了，只好不移植了。运算符重载是一个很不错的功能，它能使很多操作简单地完成，如果VB支持它，就真的是完美语言了。 <br />   <br />  好了，想必最麻烦的地方已经说完了，剩下的就是简单的Copy了。虽然有些地方还没有说清楚，但基本上阐明了两种语言的不同（一看，不同还挺多的吧），反正也不用移植大的工程，了解这些内容主要是为了利用双倍的利用已经存在的代码，但愿本文对你有用。</p>
<img src ="http://www.blogjava.net/songfei/aggbug/50774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2006-06-06 15:17 <a href="http://www.blogjava.net/songfei/articles/50774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Ajax.Net的快速入门 </title><link>http://www.blogjava.net/songfei/articles/41823.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Wed, 19 Apr 2006 02:24:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/41823.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/41823.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/41823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/41823.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/41823.html</trackback:ping><description><![CDATA[
		<table class="p21" style="BORDER-BOTTOM: #000000 1px solid" cellspacing="0" cellpadding="4" width="100%" border="0">
				<tbody>
						<tr>
								<td align="middle">
										<b>关于Ajax.Net的快速入门 </b>
								</td>
						</tr>
				</tbody>
		</table>
		<table class="content" cellspacing="0" cellpadding="2" width="100%" bgcolor="#fff7bc" border="0">
				<tbody>
						<tr>
								<td align="middle">
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<script language="JavaScript"><![CDATA[
function doZoom(size){
document.getElementById('zoom').style.fontSize=size+'px';
}
]]&gt;</script>
		<table cellspacing="0" cellpadding="0" width="95%" border="0">
				<tbody>
						<tr>
								<td class="p14" style="WORD-WRAP: break-word">
										<span id="zoom">
												<span id="tech_art_center">
												</span>
												<p style="TEXT-INDENT: 2em">现在的项目准备用ajax，用ajax.net实现，而不是atlas，所以先看下ajax.net，Ajax.Net现在的最新版本是AjaxPro5.11.4.2,下载地址是：www.schwarz-interactive.de 
</p>
												<p style="TEXT-INDENT: 2em">首先我们新建个项目，名字是AjaxPro,我用的是vs2005beta2版本。 
</p>
												<p style="TEXT-INDENT: 2em">右击站点名字点add reference添加对我们刚刚下载来的那个叫AjaxPro.2.dll的引用，如果你用的是vs2003，则添加对AjaxPro.dll的引用，然后我们在添加个web.config文件（很郁闷的是vs2005不再自动添加web.config文件拉），修改web.config如下： 
</p>
												<p style="TEXT-INDENT: 2em">
												</p>
												<center>
														<ccid_nobr>
																<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
																		<tbody>
																				<tr>
																						<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
																								<pre>
																										<ccid_code>&lt;system.web&gt; &lt;httpHandlers&gt; 
&lt;add verb="POST,GET" path="ajaxpro/*.ashx" 
type="AjaxPro.AjaxHandlerFactory, 
AjaxPro.2"/&gt; &lt;/httpHandlers&gt;</ccid_code>
																								</pre>
																						</td>
																				</tr>
																		</tbody>
																</table>
														</ccid_nobr>
												</center>
												<p style="TEXT-INDENT: 2em">意思是所有的ajaxpro/*.ashx请求都由Ajax.PageHandlerFactory处理，而不是由默认的System.Web.UI.PageHandlerFactory处理程序工厂来处理。 
</p>
												<p style="TEXT-INDENT: 2em">我们现在给Default.aspx.cs文件添加个名字空间namespace MyDemo，这里更加郁闷的是为什么vs2005beta2怎么不给你自动添加名字空间啊？和2003怎么完全不同呢？ 
</p>
												<p style="TEXT-INDENT: 2em">现在我们写个AjaxMethod服务器端方法，他和普通的服务器方法唯一不同的地方就是他必须要在方法的上面添加个[AjaxPro.AjaxMethod],代码如下： 
</p>
												<p style="TEXT-INDENT: 2em">
												</p>
												<center>
														<ccid_nobr>
																<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
																		<tbody>
																				<tr>
																						<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
																								<pre>
																										<ccid_code>[AjaxPro.AjaxMethod]
public DateTime GetServerTime()
{
return DateTime.Now;
}
[AjaxPro.AjaxMethod]public int 
AddTwo(int firstInt, int secondInt)
{
return firstInt + secondInt;
}</ccid_code>
																								</pre>
																						</td>
																				</tr>
																		</tbody>
																</table>
														</ccid_nobr>
												</center>
												<p style="TEXT-INDENT: 2em">我们还必须在Page_Load里面把这个类注册下，如下： 
</p>
												<p style="TEXT-INDENT: 2em">
												</p>
												<center>
														<ccid_nobr>
																<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
																		<tbody>
																				<tr>
																						<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
																								<pre>
																										<ccid_code>protected void Page_Load
(object sender, EventArgs e)
{
AjaxPro.Utility.RegisterTypeForAjax
(typeof(_Default));
}</ccid_code>
																								</pre>
																						</td>
																				</tr>
																		</tbody>
																</table>
														</ccid_nobr>
												</center>
												<p style="TEXT-INDENT: 2em">这个时候我们还必须修改aspx页面的指令行，因为我们在后台搞了个名字空间，如下：Inherits="MyDemo._Default"也就是要把名字空间也写上。我们再写客户端脚本来调用服务器方法。代码里有详细的注释，前台Default.aspx代码： 
</p>
												<p style="TEXT-INDENT: 2em">
												</p>
												<center>
														<ccid_nobr>
																<table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1">
																		<tbody>
																				<tr>
																						<td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6">
																								<pre>
																										<ccid_code>&lt;%@ Page Language="C#" 
AutoEventWireup="true"CodeFile="Default.aspx.cs" 
Inherits="MyDemo._Default" %&gt;
&lt;!DOCTYPE html PUBLIC "-
//W3C//DTD XHTML 1.1//EN" 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" &gt;
&lt;head runat="server"&gt;&lt;title&gt;Untitled Page
&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;form id="form1"
runat="server"&gt;&lt;div&gt;&lt;input id="Button1"
type="button" value="获得服务器时间" 
onclick="getServerTime();" /&gt;&lt;input 
id="Text1" type="text" /&gt;&lt;input 
id="Text2" type="text" /&gt;&lt;input
id="Button2" type="button" 
value="得到两个文本框的和" 
onclick="add(document.getElementById('Text1').
value,document.getElementById('Text2').value)" 
/&gt;&lt;/div&gt;&lt;/form&gt;&lt;script 
type="text/javascript"&gt;
function getServerTime()
{
//MyDemo._Default.GetServerTime()
得到从服务器传来的数据是object，
要写.valuealert
(MyDemo._Default.GetServerTime().value);
}
function add(a,b)
{
//把文本框的值转换成intvar 
a1 = parseInt(a);var b1 = parseInt(b);
//第1、2参数为服务器方法所需要的参数，
后面一个是如果服务器返回数据
//客户端要处理这些数据的js函数名，
他有个参数就是从服务器传来的数据
MyDemo._Default.AddTwo(a1,b1,getAdd);
}
function getAdd(rel)
{
//要加上.valuealert(rel.value);
}
&lt;/script&gt;&lt;/body&gt;&lt;/html&gt;
后台Default.aspx.cs代码：
using System;using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;using 
System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace MyDemo
{
public partial class _Default : 
System.Web.UI.Page{protected void 
Page_Load(object sender, EventArgs e){AjaxPro.Utility.RegisterTypeForAjax
(typeof(_Default));
}
[AjaxPro.AjaxMethod]public 
DateTime GetServerTime()
{return DateTime.Now;
}[AjaxPro.AjaxMethod]public int AddTwo
(int firstInt, int secondInt)
{
return firstInt + secondInt;
}}} 
按F5运行结果如下，
firefox里面测试通过： 
using System;using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace MyDemo
{
public partial class _Default :
System.Web.UI.Page
{
protected void Page_Load
(object sender, EventArgs e)
{AjaxPro.Utility.RegisterTypeForAjax
(typeof(_Default));}
[AjaxPro.AjaxMethod]public DateTime 
GetServerTime(){return DateTime.Now;
}
[AjaxPro.AjaxMethod]public 
int AddTwo(int firstInt, 
int secondInt)
{return firstInt + secondInt;}}}</ccid_code>
																								</pre>
																						</td>
																				</tr>
																		</tbody>
																</table>
														</ccid_nobr>
												</center>
										</span>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/songfei/aggbug/41823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2006-04-19 10:24 <a href="http://www.blogjava.net/songfei/articles/41823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编写高性能Web 应用程序的10 个技巧</title><link>http://www.blogjava.net/songfei/articles/23039.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 13:18:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/23039.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/23039.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/23039.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/23039.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/23039.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 固定链接关闭http://spaces.msn.com/members/siskin/Blog/cns!1p4AQvJXh0OPYIKEvlZ7bkbg!108.entry编写高性能 Web 应用程序的 10 个技巧编写高性能 Web 应用程序的 10 个技巧 发布日...&nbsp;&nbsp;<a href='http://www.blogjava.net/songfei/articles/23039.html'>阅读全文</a><img src ="http://www.blogjava.net/songfei/aggbug/23039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 21:18 <a href="http://www.blogjava.net/songfei/articles/23039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用客户端脚本</title><link>http://www.blogjava.net/songfei/articles/23037.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 13:16:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/23037.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/23037.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/23037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/23037.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/23037.html</trackback:ping><description><![CDATA[<TABLE class="fixedTable blogpost" cellSpacing=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=ellipse><SPAN class=bvTitle id=subjcns!1p4AQvJXh0OPYIKEvlZ7bkbg!108><STRONG>使用客户端脚本</STRONG></SPAN></TD></TR>
<TR>
<TD class=bvh8><STRONG></STRONG></TD></TR>
<TR>
<TD id=msgcns!1p4AQvJXh0OPYIKEvlZ7bkbg!108>使用客户端脚本 
<DIV class=date>发布日期： 9/20/2004 | 更新日期： 9/20/2004</DIV>
<DIV class=overview>
<DIV id="">
<P>Scott Mitchell</P></DIV>
<DIV id="">
<P>4GuysFromRolla.com</P></DIV>
<DIV id="">
<P><B>摘要</B>：尽管 ASP.NET 在服务器上执行其大多数操作，但是某些操作在客户端进行处理可能会更好。Scott Mitchell 说明了 ASP.NET 页面和控件如何添加客户端代码。</P></DIV>
<DIV id="">
<P><A href="http://download.microsoft.com/download/A/8/C/A8C44419-05F8-450C-9FB4-F1AED34527F1/MSDNClientSideScript.msi" target=_blank><FONT color=#004377>下载本文的源代码</FONT></A>。</P></DIV></DIV><IMG title="" height=6 alt=* src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/3squares.gif" width=30 border=0> 
<DIV style="HEIGHT: 18px"></DIV>本页内容 <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EJAA"><IMG height=9 alt=简介 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EJAA"><FONT color=#004377>简介</FONT></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EIAA"><IMG height=9 alt=创建基类作为添加客户端脚本的基础 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EIAA"><FONT color=#004377>创建基类作为添加客户端脚本的基础</FONT></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EHAA"><IMG height=9 alt=从代码隐藏类添加客户端脚本 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EHAA"><FONT color=#004377>从代码隐藏类添加客户端脚本</FONT></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EGAA"><IMG height=9 alt=根据对用户操作的响应执行客户端代码 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EGAA"><FONT color=#004377>根据对用户操作的响应执行客户端代码</FONT></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EFAA"><IMG height=9 alt=实现常用客户端功能 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EFAA"><FONT color=#004377>实现常用客户端功能</FONT></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EEAA"><IMG height=9 alt=小结 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EEAA"><FONT color=#004377>小结</FONT></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EDAA"><IMG height=9 alt=相关书籍 hspace=4 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_down.gif" width=7 vspace=2 border=0></A> <A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#EDAA"><FONT color=#004377>相关书籍</FONT></A> 
<DIV id=""><A name=EJAA></A>简介 
<DIV id="">
<P>当使用动态的、基于 Web 的脚本技术时，与传统 ASP 或 PHP 类似，开发人员必须对客户端和服务器间的逻辑、暂时和物理分隔有着敏锐的理解。例如，对于触发服务器端代码执行的用户操作，使用传统 ASP 的开发人员必须明确地使用户的浏览器将请求返回到 Web 服务器。创建这样的交互可能会轻易地占用大量开发时间，并且导致不易读的代码。</P></DIV>
<DIV id="">
<P>Microsoft ASP.NET 通过使用 Web 窗体，有助于减轻将用户事件绑定到特定服务器端代码执行的负担，这就模糊了客户端和服务器间的界线。使用 ASP.NET 和最少的工作，开发人员就可以快速地创建如下的网页，它具有大量的交互式用户界面元素按钮、下拉列表等，而这些都基于最终用户的操作，可以选择性地运行服务器端代码。例如，利用 ASP.NET 添加下拉列表，只要选定的下拉列表项目更改则执行某些操作，您只需添加 <B>DropDownList</B> Web 控件、将其 <B>AutoPostBack</B> 属性设置为 True，然后为该下拉列表创建一个 <B>SelectedIndexChanged</B> 事件处理程序。如果利用传统的 ASP 完成上述任务，则会要求编写许多复杂的 HTML、客户端 JavaScript 和服务器端脚本代码；利用 ASP.NET，则为您提供了必要的脚本代码和服务器端事件模型。</P></DIV>
<DIV id="">
<P>尽管在执行客户端操作时，ASP.NET 中的 Web 窗体极大地简化了运行服务器端脚本，但是，如果误用这种功能可能会导致无法接受的性能。尽管 Web 窗体隐藏了所涉及的复杂性，每次需要执行服务器端代码时，最终用户的浏览器必须通过重新提交窗体，将请求返回到 Web 服务器。当提交窗体时，所有窗体字段（文本框、下拉列表和复选框等）必须同时返回它们的值。此外，页面的视图状态也被返回到 Web 服务器。总而言之，每次回发网页时，几千字节的数据将需要潜在地发送回 Web 服务器。于是，经常回发可能很快就会导致 Web 应用程序不可使用，尤其是对于那些仍然使用拨号连接的用户。通过将功能推到客户端可以降低经常回发的需要。</P></DIV>
<DIV id="">
<P><B>注</B> ASP.NET Web 窗体发出一个标题为 VIEWSTATE 的隐藏窗体字段，它包含 Web 窗体中 Web 控件已更改状态的基于 64 位编码的表示。根据出现的 Web 控件，视图状态的范围可以从几十字节到几万字节。要学习有关视图状态的更多知识，请查阅我的文章 <A href="http://msdn.microsoft.com/library/en-us/dnaspp/html/viewstate.asp" target=_blank><FONT color=#004377>Understanding ASP.NET View State</FONT></A>。</P></DIV>
<DIV id="">
<P>利用传统的 ASP，添加数据驱动、自定义客户端脚本非常简单，但并不是非常易读。例如，要在传统的 ASP 中显示根据某个 ID 字段加载 URL 的弹出窗口，您可以使用 语法来插入 ID 字段的值，在适当的客户端脚本中进行输入。ASP.NET 允许您利用 Page 类中的各种方法，创建这种数据驱动的客户端脚本。</P></DIV>
<DIV id="">
<P>本文分析了向 ASP.NET 网页添加客户端脚本的技术。客户端脚本是运行在访问者浏览器中的脚本代码，如其名字所示。我们将看到如何完成常见的客户端任务，例如显示警告、确认框和弹出窗口。（客户端脚本窗体字段验证的一个主要用途可能与 ASP.NET 主题有点不相关，因为验证程序 Web 控件提供了随取随用的客户端窗体验证。）本文的重点在于插入客户端脚本的服务器端类、方法和技术；我们不会详细地分析实际的客户端脚本，因为该信息涉及了围绕 Web 的众多其他文章和站点。</P></DIV></DIV>
<DIV id="">
<DIV><A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><FONT color=#004377>返回页首</FONT></A></DIV><A name=EIAA></A>创建基类作为添加客户端脚本的基础 
<DIV id="">
<P>传统的 ASP 和 ASP.NET 之间的主要差别之一在于各自技术的编程模型。ASP 页面是原子的、程序上的脚本，解释每个页面的访问。然而，ASP.NET 完全是面向对象的编程技术。所有 ASP.NET 网页都是带有属性、方法和事件的类。所有网页直接或间接地派生自 <B>System.Web.UI</B> 命名空间中的 <B>Page</B> 类，<B>Page</B> 类包含了 ASP.NET 网页的基本功能。</P></DIV>
<DIV id="">
<P>面向对象编程的概念之一就是继承。继承使您可以创建一个扩展其他类功能的新类。（如果类 <I>B</I> 继承类 <I>A</I>，也可以说扩展了 <I>A</I>；类 <I>A</I> 被称为基类。）当使用代码隐藏模型来创建 ASP.NET 网页时，可以非常清楚地看到代码隐藏类继承了 <B>Page</B> 类：</P></DIV>Public Class WebForm1 Inherits System.Web.UI.Page ... End Class 
<DIV id="">
<P>通过使您的代码隐藏类继承 <B>Page</B> 类，它自动接收在 <B>Page</B> 类中继承的功能，例如 <B>Request</B>、<B>Response</B>、<B>Session</B> 和 <B>ViewState</B> 对象以及常见事件，如 <B>Init</B>、<B>Load</B>、<B>Render</B> 等等。我们将在本文中看到，如果您需要可用于所有 ASP.NET 网页的某个常见功能，一种方法是创建派生自 <B>Page</B> 类并具有完成这些所需增强功能的其他方法和属性的类。然后，要使 ASP.NET 网页利用这些增强功能，我们只需更新页面代码隐藏类中的 <B>Inherits</B> 语句，以使用扩展 <B>Page</B> 类的类。 </P></DIV>
<DIV id="">
<P>在本文中，我们将创建一个名为 <B>ClientSidePage</B> 的类，它派生自 <B>Page</B> 类并提供额外的方法以协助执行常见的客户端任务。通过让代码隐藏类继承 <B>ClientSidePage</B>，而不是继承 <B>Page</B>，添加脚本代码将会像调用方法和传送几个参数那样简单。具体说来，该类包括用于下列用途的方法： </P></DIV>• 
<DIV id="">
<P>显示模式客户端对话框。 </P></DIV>• 
<DIV id="">
<P>在页面加载时将焦点设置到特定的窗体字段。 </P></DIV>• 
<DIV id="">
<P>使用模式确定对话框来确定用户是否希望回发该窗体。 </P></DIV>• 
<DIV id="">
<P>显示弹出窗口。 </P></DIV>
<DIV id="">
<P>在我们深入研究 <B>ClientSidePage</B> 类之前，首先让我们分析一下 <B>Page</B> 类中的有关方法，以便将客户端脚本插入到网页中。在我们讨论这些 <B>Page</B> 方法后，我们将开始利用 <B>ClientSidePage</B> 类扩展它们的功能，并且查看如何将所有内容结合在一起以及如何在 ASP.NET 网页中使用扩展的类。</P></DIV></DIV>
<DIV id="">
<DIV><A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><FONT color=#004377>返回页首</FONT></A></DIV><A name=EHAA></A>从代码隐藏类添加客户端脚本 
<DIV id="">
<P>所有 ASP.NET 网页必须直接或间接地派生自 <B>System.Web.UI </B>命名空间中的 <B>Page</B> 类。<B>Page</B> 类包含正常运行的网页所要求的方法、属性和事件的基本集合。在该类的众多方法中，一些方法旨在将客户端脚本插入到生成的 HTML 中。这些方法从代码隐藏类调用，因此可以用于发出数据驱动的客户端脚本。用于发出客户端脚本的相关 <B>Page</B> 类方法如下所示。</P></DIV>
<DIV id="">
<P>该基类派生自 <B>System.Web.UI.Page</B> 类，因此可以通过从代码隐藏类直接调用 <B>Page</B> 类的公共方法来访问它们。 </P></DIV>
<DIV id="">
<P><B>注</B> 要访问 <B>Page</B> 类的方法，您可以直接键入方法名，或者通过输入 <B>MyBase</B>.（对于 Microsoft Visual Basic .NET）、<B>this</B>. （对于 C#）或者 <B>Page</B>.（对于 C# 或 Visual Basic .NET），利用 Microsoft Visual Studio .NET 中的 IntelliSense 来实现。如果使用 Visual Basic .NET 作为选择的编程语言，请确保将 Visual Studio .NET 配置为不 隐藏高级成员，否则将无法看到这些客户端脚本方法。（要显示高级成员，请转到 <B>Tools</B> | <B>Options</B> | <B>Text</B><B>Editor</B> | <B>Basic</B>，然后清除<B> Hide advanced members</B> 复选框。）</P></DIV>
<DIV id="">RegisterClientScriptBlock(key, script) 
<DIV id="">
<P>在 Web 窗体已呈现的 &lt;<B>form</B>&gt; 元素之后，在包含于 Web 窗体中的任意 Web 控件之前，<B>RegisterClientScriptBlock</B> 方法会添加一个客户端脚本块。<I>key</I> 输入参数允许您指定与该脚本块相关联的唯一的密钥，而 <I>script</I> 参数包括要发出的完整的脚本代码。（这个 <I>script</I> 参数应该包括实际的 &lt;<B>script</B>&gt; 元素，同时还包括客户端 JavaScript 或 Microsoft VBScript。）</P></DIV>
<DIV id="">
<P>在通过 ASP.NET 网页的代码隐藏类发出客户端脚本时，通常情况下，<I>key</I> 参数的值就不是非常重要了。简单地选择一个说明性的密钥值。在通过自定义编译的服务器控件插入客户端脚本代码时，<I>key</I> 参数就更加适用。编译的控件有可能需要一组客户端函数。一个页面上服务器控件的多个实例可以共享这些公用客户端脚本函数，因此对于整个页面而言，这些函数只需要发出一次即可，不需要每个控件实例发送一次。例如，验证控件利用客户端代码来增强用户体验。如果页面上存在任意验证控件，这种客户端代码就必须存在，但是如果存在多个验证控件，那么全部控件都可以使用这个单个的共享函数的集合。</P></DIV>
<DIV id="">
<P>通过为脚本块提供一个密钥，利用公用客户端函数集合构建控件的控件开发人员可以检查所要求的公用函数集合是否已经被页面上控件的另一个实例添加。如果已添加，它不需要重新添加公用脚本。要检查脚本块是否已经使用相同的密钥添加，请使用 <B>IsClientScriptBlockRegistered</B>(key) 方法，它将返回布尔值，表示带有相同密钥的脚本块是否已经进行了注册。需要注意的是可以在不首先检查它是否注册的情况下添加脚本块。如果尝试利用已经注册的密钥添加脚本块，添加的脚本块将被忽略，并且原来的脚本将保持分配到该密钥。</P></DIV>
<DIV id="">
<P><B>注</B><B>IsClientScriptBlockRegistered</B> 方法在以下两种情况下尤为有用。第一，当添加相似但又独特的脚本块时它很方便，您需要确保每个脚本块都给予唯一的密钥。本文稍后分析的代码说明了“is registered”方法的实用性。第二个用途就是当构建需要某个公用脚本的控件时，尤其是如果特别的生成该脚本。通过使用 <B>IsClientScriptBlockRegistered</B> 方法，可以确保对页面上服务器控件的所有脚本通用的脚本在每次页面加载时只生成一次，而不是对页面上的每个控件实例都生成一次。</P></DIV>
<DIV id="">
<P><B>RegisterClientScriptBlock</B> 方法对于添加客户端脚本非常有用，该脚本不依赖于 Web 窗体内出现的任意窗体字段。该方法的常见使用就是显示客户端警告框。例如，设想您具有一个带有一些 <B>TextBox</B> Web 控件和一个“Save”按钮的网页。<B>TextBox</B> 控件可能会具有来自数据库的特殊值。设想该页面允许用户修改这些值并通过单击“Save”按钮提交他们所做的更改。当单击“Save”时，网页将会回发，并且会触发按钮的 <B>Click</B> 事件。您可以为更新数据库的事件创建一个服务器端事件处理程序。要使用户知道他们的更改已经保存，您可能希望显示一个警告框“Your changes have been saved”。通过将以下代码行添加到按钮的 <B>Click</B> 事件处理程序中，可以实现这个任务：</P></DIV>RegisterClientScriptBlock("showSaveMessage", _ "&lt;script language=""JavaScript""&gt; _ alert('Your changes have been saved.'); _ &lt;/script&gt;") 
<DIV id="">
<P>上述代码将会在页面的 &lt;<B>form</B>&gt; 内添加指定的脚本内容，但是在该窗体的内容前。当在用户浏览器中生成页面时，他们将会看到根据页面加载显示的客户端警告框，如图 1 所示。</P></DIV>&lt;form method="post" ...&gt; &lt;script language="JavaScript"&gt; alert('Your changes have been saved.'); &lt;/script&gt; ... &lt;/form&gt; 
<DIV style="WIDTH: 230px"><IMG height=119 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig01.gif" width=230 border=0><BR>
<P class=figureCaption><B>图</B><B> 1</B>. 客户端 JavaScript 的结果</P>
<DIV class=figureRule></DIV></DIV>
<DIV id="">
<P><B>注</B> 上面示例中一个潜在地不需要的副作用就是，警告框将会在浏览器接收到 &lt;<B>form</B>&gt; 标记后立即显示。在用户单击警告框的“OK”按钮之前，浏览器将挂起网页的呈现。这意味着用户在单击“OK”之前，将看到一个空白的浏览器页面。如果希望在显示警告框之前完全显示该页面，您可以使用 <B>RegisterStartupScript</B> 方法（我们将在下面进行讨论），在 &lt;<B>form</B>&gt; 元素的结尾处插入 JavaScript。</P></DIV></DIV>
<DIV id="">RegisterStartupScript(key, script) 
<DIV id="">
<P><B>RegisterStartupScript</B> 方法与 <B>RegisterClientScriptBlock</B> 方法非常相似。主要的区别在于发出客户端脚本的位置。在 &lt;<B>form</B>&gt; 元素开始后，在窗体的内容前，记住用 <B>RegisterClientScriptBlock</B> 发出脚本。另一方面，<B>RegisterStartupScript</B> 在窗体的<I>结尾</I> 处、在所有窗体字段后，添加指定的脚本。使用 <B>RegisterStartupScript</B> 来放置与呈现的 HTML 元素交互的客户端脚本。（稍后我将研究根据页面加载将焦点设置到窗体字段的示例；要完成这个操作，您将要使用 <B>RegisterStartupScript</B> 方法。）</P></DIV>
<DIV id="">
<P>与 <B>RegisterClientScriptBlock</B> 相似，由 <B>RegisterStartupScript</B> 添加的脚本块需要一个唯一的密钥值。同样，该密钥值主要由自定义控件开发人员使用。并不奇怪，还有一个 <B>IsStartupScriptRegistered(key) </B>方法，它返回布尔值，表示带有指定密钥 的脚本块是否已经进行了注册。</P></DIV>
<DIV id="">
<P><B>注</B> 有关使用 <B>RegisterStartupScript</B> 和 <B>RegisterClientScriptBlock</B> 来创建自定义编译的服务器控件的详细信息，请阅读我以前的文章： <A href="http://msdn.microsoft.com/library/en-us/dnaspp/html/aspnet-injectclientsidesc.asp" target=_blank><FONT color=#004377>Injecting Client-Side Script from an ASP.NET Server Control</FONT></A>.</P></DIV></DIV>
<DIV id="">RegisterArrayDeclaration(arrayName, arrayValue) 
<DIV id="">
<P>如果需要创建带有某些设置值的客户端 JavaScript <B>Array</B> 对象，请使用该方法向特定的数组添加值。例如，当使用 ASP.NET 网页中的验证控件时，就会构建 <B>Array</B> 对象 (<B>Page_Validators</B>)，以包含对页面上验证控件集合的引用。当提交窗体时，就会枚举该数组以检查各种验证控件是否有效。</P></DIV>
<DIV id="">
<P>要将值 1、2 和 3 添加到名为 <B>FavoriteNumbers</B> 的客户端 <B>Array</B> 对象，要使用以下服务器端代码：</P></DIV>RegisterArrayDeclaration("FavoriteNumbers", "1") RegisterArrayDeclaration("FavoriteNumbers", "2") RegisterArrayDeclaration("FavoriteNumbers", "3") 
<DIV id="">
<P>这段代码会发出以下客户端脚本：</P></DIV>&lt;script language="javascript"&gt; &lt;!-- var FavoriteNumbers = new Array(1, 2, 3); // --&gt; &lt;/script&gt; 
<DIV id="">
<P>请注意，被传递的每个数组值都必须是字符串；但是，呈现的客户端脚本将 <B>Array</B> 对象的值设置为字符串的内容。也就是说，如果希望创建带有字符串值“Scott”和“Jisun”的 <B>Array</B>，要使用以下代码：</P></DIV>RegisterArrayDeclaration("FavoriteFolks", "'Scott'") RegisterArrayDeclaration("FavoriteFolks ", "'Jisun'") 
<DIV id="">
<P>请注意，第二个输入参数是包含 'Scott' 和 'Jisun' 的字符串 － 文本由单撇号分隔。这会显示以下客户端脚本：</P></DIV>&lt;script language="javascript"&gt; &lt;!-- var FavoriteFolks = new Array('Scott', 'Jisun'); // --&gt; &lt;/script&gt; </DIV>
<DIV id="">RegisterHiddenField(hiddenFieldName, hiddenFieldValue) 
<DIV id="">
<P>在传统的 ASP 中，通常需要将各种信息从一个页面分发到另一个页面。完成这个操作的常用方法就是使用隐藏窗体字段。（隐藏窗体字段是不显示的窗体字段，但是它的值会根据窗体的提交而发送。创建隐藏窗体字段的语法是 。）在 ASP.NET 中，通过自定义隐藏窗体字段传递信息的需要会极大地减少，因为页面中的控件状态会自动保持。但是，如果您发现需要创建自定义隐藏窗体字段，可以通过 <B>RegisterHiddenField</B> 方法来完成。</P></DIV>
<DIV id="">
<P><B>RegisterHiddenField</B> 方法接受两个输入参数。隐藏字段的名称和值。例如，要创建带有名称 foo 和值 bar 的隐藏窗体字段，请使用以下代码：</P></DIV>RegisterHiddenField("foo", "bar") 
<DIV id="">
<P>这会在页面的 &lt;<B>form</B>&gt; 元素中添加隐藏窗体字段，如下所示：</P></DIV>&lt;form name="_ctl0" method="post" action="test.aspx" id="_ctl0"&gt; &lt;input type="hidden" name="foo" value="bar" /&gt; ... &lt;/form&gt; </DIV>
<DIV id="">理解客户端元素是如何呈现的 
<DIV id="">
<P><B>Page</B> 类包含负责呈现在上面讨论的方法中注册的客户端脚本的两个 <B>internal</B> 方法：<B>OnFormRender</B> 和 <B>OnFormPostRender</B>。（标记为 <B>internal</B> 的方法只能被相同程序集中的其他类调用。因此，无法从 ASP.NET Web 应用程序中的代码隐藏类调用 <B>Page</B> 的 <B>internal</B> 方法。）这两个方法都在 <B>HtmlForm</B> 类的 <B>RenderChildren</B> 方法中进行调用。位于 <B>System.Web.UI.HtmlControls</B> 命名空间中的 <B>HtmlForm</B> 类表示 Web 窗体；也就是说，ASP.NET 网页中的服务器端窗体&lt;form runat="server"&gt;...&lt;/form&gt; 在页面的实例化阶段中作为 <B>HtmlForm</B> 类的实例加载。</P></DIV>
<DIV id="">
<P>因为由 <B>Page</B> 类的众多方法注册的客户端脚本是在 <B>OnFormRender</B> 和 <B>OnFormPostRender</B> 方法中呈现的，并且因为这些方法只能由 <B>HtmlForm</B> 类进行调用，所以通过这些方法以编程方式添加的客户端脚本，只有在网页包含 Web 窗体时才会呈现。也就是说，通过上面讨论的任意方法以编程方式添加的任意脚本元素，在 ASP.NET 网页包含服务器端窗体（&lt;form runat="server"&gt;...&lt;/form&gt;）时只会在页面的最后标记中发出。</P></DIV>
<DIV id="">
<P>通过首先添加开始 &lt;<B>form</B>&gt; 元素，会呈现 ASP.NET 网页上的 Web 窗体。之后，会调用 Web 窗体的 <B>RenderChildren</B> 方法，它包含三行代码：</P></DIV>Page.OnFormRender(...) MyBase.RenderChildren(...) Page.OnFormPostRender(...) 
<DIV id="">
<P>对 <B>Page</B> 类的 <B>OnFormRender</B> 方法的调用会添加以下标记： </P></DIV>• 
<DIV id="">
<P>通过对 <B>RegisterHiddenField</B> 进行调用而添加的任意隐藏窗体字段。 </P></DIV>• 
<DIV id="">
<P>隐藏窗体字段中名为<B> __VIEWSTATE</B> 的基于 64 位编码的视图状态。 </P></DIV>• 
<DIV id="">
<P>通过对 <B>RegisterClientScriptBlock</B> 进行调用而添加的任意脚本块。 </P></DIV>
<DIV id="">
<P>Web 窗体的 <B>RenderChildren</B> 方法中的第二行代码调用基类的 <B>RenderChildren</B> 方法，它会在 Web 窗体中呈现内容。在呈现所有窗体的内容后，对 <B>Page</B> 类的 <B>OnFormPostRender</B> 方法进行调用，这将会添加以下客户端内容： </P></DIV>• 
<DIV id="">
<P>由 <B>RegisterArrayDeclaration</B> 方法添加的任意 <B>Array</B> 对象。 </P></DIV>• 
<DIV id="">
<P>通过对 <B>RegisterStartupScript</B> 进行调用而添加的任意脚本块。 </P></DIV>
<DIV id="">
<P>最后，在 Web 窗体的 <B>RenderChildren</B> 方法完成后，则会呈现关闭窗体标记 ()。图 2 以图表形式说明了这个呈现过程。</P></DIV>
<DIV id="">
<P><B>注</B> 图 2 假设您有些熟悉 ASP.NET 页面的生命周期。如果您对学习更多有关页面生命周期的知识感兴趣，请考虑阅读 <A href="http://msdn.microsoft.com/library/en-us/dnaspp/html/viewstate.asp" target=_blank><FONT color=#004377>Understanding ASP.NET View State</FONT></A>，将重点放在标题为“The ASP.NET Page Life Cycle”的节上。</P></DIV>
<DIV style="WIDTH: 450px"><IMG height=736 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig02thumb.gif" width=450 border=0><BR>
<P class=figureCaption><B>图</B><B> 2.</B> ASP.NET 中呈现的页面</P>
<DIV class=figureRule></DIV></DIV></DIV>
<DIV id="">分析脚本块的呈现顺序 
<DIV id="">
<P>乍看 Page 类的注册方法，在网页中呈现的已注册元素的顺序好像是对应于它们被添加到代码中的顺序。也就是说，设想 ASP.NET 网页的代码隐藏类中有以下两行代码：</P></DIV>RegisterClientScriptBlock("showSaveMessage", _ "&lt;script language=""JavaScript""&gt;var name='" &amp; _ someDataDrivenValue &amp; "'; &lt;/script&gt;") RegisterClientScriptBlock("showSaveMessage", _ "&lt;script language=""JavaScript""&gt;alert('Hello, ' + name + '!'); &lt;/script&gt;") 
<DIV id="">
<P>当发现页面呈现以下客户端脚本块（假设 someDataDriveValue 的值为 Sam）时，您不要太奇怪：</P></DIV>&lt;script language="JavaScript"&gt;var name='Sam';&lt;/script&gt; &lt;script language="JavaScript"&gt;alert('Hello, ' + name + '!');&lt;/script&gt; 
<DIV id="">
<P>访问该页面的用户将会看到一个警告框显示“Hello, Sam!”。</P></DIV>
<DIV id="">
<P>基于这个测试，您可能会认为这样的事实始终成立：在 HTML 页面中发出脚本块的顺序就是在服务器端代码中为它们指定的顺序。但是，这是一个不正确的假设，并且可以导致页面中断。例如，设想前面添加的脚本块在 HTML 页面中以相反的顺序发出。那么，您将会得到：</P></DIV>&lt;script language="JavaScript"&gt;alert('Hello, ' + name + '!');&lt;/script&gt; &lt;script language="JavaScript"&gt;var name='Sam';&lt;/script&gt; 
<DIV id="">
<P>这将会显示警告框“Hello, !”，因为变量 name 尚未分配值。显然，有些时候发出脚本块的顺序非常重要的。</P></DIV>
<DIV id="">
<P><B>Page</B> 类的注册方法 － <B>RegisterClientScriptBlock</B>、<B>RegisterStartupScript</B>、<B>RegisterArrayDeclaration</B> 和 <B>RegisterHiddenFields</B> － 全部将提供的脚本内容写入到内部 <B>HybridDictionary</B> 中。<B>HybridDictionary</B> 是在 <B>System.Collections.Specialized</B> 命名空间中发现的数据结构，设计用于在有很多项目未知的字典中存储项目。对于小型的项目集合，<B>ListDictionary</B> 是最有效的数据结构，但是对于较大的字典，<B>Hashtable</B> 会更有效。<B>HybridDictionary</B> 分离差异 － 它通过使用 <B>ListDictionary</B> 存储项目来开始。当 <B>ListDictionary</B> 添加了它的第九个项目后，<B>HybridDictionary</B> 会从使用 <B>ListDictionary</B> 切换到使用 <B>Hashtable</B>。</P></DIV>
<DIV id="">
<P>尽管这种方法对于性能而言非常理想，但是如果您使用几个脚本块而且脚本块的顺序非常重要，那么它可能会带来严重的破坏。这是因为，<B>ListDictionary</B> 维护元素被添加的顺序，而 <B>Hashtable</B> 没有进行维护。因此，如果您将八个或更少项目添加到任意一个特定的注册方法中，项目将会以它们被添加的顺序发出。但是，如果添加了第九个项目，脚本发出的顺序看起来将是随机的。</P></DIV>
<DIV id="">
<P><B>注</B><B>ListDictionary</B> 使用 <I>linked list </I>存储它的元素，而 <B>Hashtable</B> 将它的元素存储在数组中，该数组的内容按照字符串键的哈希值进行排序。有关链接列表和哈希表的完整讨论已经远远超出了本文所讨论的范围。有关详细信息，包括对其性能的分析，请考虑阅读 <A href="http://msdn.microsoft.com/library/en-us/dv_vstechart/html/datastructures_guide.asp" target=_blank><FONT color=#004377>An Extensive Examination of Data Structures</FONT></A>，尤其是 <A href="http://msdn.microsoft.com/library/en-us/dv_vstechart/html/datastructures_guide2.asp" target=_blank><FONT color=#004377>Part 2</FONT></A> 和 <A href="http://msdn.microsoft.com/library/en-us/dv_vstechart/html/datastructures_guide4.asp" target=_blank><FONT color=#004377>Part 4</FONT></A>。</P></DIV>
<DIV id="">
<P>如果您计划出现如下情况：可能会存在使用特殊注册方法添加的多于八个客户端元素，并且元素的出现顺序比较重要，那么您可能希望研究一下 <A href="http://www.peterblum.com/Home.aspx" target=_blank><FONT color=#004377>Peter Blum</FONT></A> 的免费的 <A href="http://www.peterblum.com/RegScripts/RegScriptsHome.aspx" target=_blank><FONT color=#004377>RegisterScripts</FONT></A> 库。对于所发出客户端元素的顺序，RegisterScripts 提供了更大的控制能力，并且还提供了无需手动添加 &lt;<B>script</B>&gt; 标记的选项，当利用 <B>RegisterClientScriptBlock</B> 或 <B>RegisterStartupScript</B> 方法包括客户端脚本时，您必须添加此标记。</P></DIV></DIV></DIV>
<DIV id="">
<DIV><A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><FONT color=#004377>返回页首</FONT></A></DIV><A name=EGAA></A>根据对用户操作的响应执行客户端代码 
<DIV id="">
<P>对于插入页面加载时运行的客户端代码而言，<B>Page</B> 类的注册方法非常理想，但是在很多情况下，我们希望根据对最终用户操作的响应来运行代码。例如，我们可能希望当用户单击按钮时显示确认对话框，或者当下拉列表的选定项目发生变化时调用特殊的客户端 JavaScript 功能。</P></DIV>
<DIV id="">
<P>HTML 元素具有您可以点击的大量客户端事件，并且当触发事件时可以执行客户端代码。所要求的标记只是在 HTML 元素的标记中作为一个属性。例如，要在单击某个按钮时显示警告框，可以添加以下代码：</P></DIV>&lt;input type="button" value="Click me to see an alert box!" onclick="alert('Here it is!');" /&gt; 
<DIV id="">
<P>要在客户端事件触发时运行客户端代码，可以将适当的属性添加到 HTML 元素中。对于 Web 控件，可以借助于编程方式使用 <B>Attributes</B> 集合添加客户端属性。例如，设想您具有一个 <B>TextBox</B> Web 控件，只要呈现的文本框获得焦点，您就希望它突出显示为黄色。要完成上述操作，您要将 <B>TextBox</B> Web 控件的呈现 HTML 添加如下所示的代码：</P></DIV>&lt;input type="text" onfocus="this.style.backgroundColor='yellow';" onblur="this.style.backgroundColor='white';" /&gt; 
<DIV id="">
<P>要完成这个标记，我们可以借助编程方式通过 <B>Attributes</B> 集合设置 <B>TextBox</B> Web 控件的 <B>onfocus</B> 和 <B>onblur</B> 客户端属性，如下所示：</P></DIV>TextBoxControl.Attributes("onfocus") = "this.style.backgroundColor='yellow';" TextBoxControl.Attributes("onblur") = "this.style.backgroundColor='white';" 
<DIV id="">
<P>将客户端代码与客户端事件结合在一起的这种技术通常用于提供丰富的、交互式的用户体验。稍后，我们将会在本文中说明如何使用这种技术来显示基于用户操作的确认对话框。</P></DIV></DIV>
<DIV id="">
<DIV><A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><FONT color=#004377>返回页首</FONT></A></DIV><A name=EFAA></A>实现常用客户端功能 
<DIV id="">
<P>在我们研究 ASP.NET 方法（涉及动态地将客户端脚本添加到网页）后，让我们将注意力转移到这个知识。本文的其余部分重点讲述常用客户端任务，例如显示警告框、确认框、弹出窗口等等。具体说来，我们将创建包含一组方法的类，这组方法可用在 ASP.NET 项目中，从而快速、便捷地提供这样的功能。</P></DIV>
<DIV id="">
<P>我们将要分析的、贯穿本文剩余部分的 Visual Basic .NET 代码可以在本文的代码下载中获得。</P></DIV>
<DIV id="">显示警告框 
<DIV id="">
<P>一个常用的客户端要求就是显示警告框。警告框是一个客户端模式对话框，通常用于为最终用户提供某些重要的信息。警告框的示例如图 1 所示。警告框是通过客户端 JavaScript <B>alert</B> 函数来进行显示的，该函数接受一个单个的参数，即要显示的消息。显示警告框相当简单和直接；实际上，本文前面已经显示了一个示例。</P></DIV>
<DIV id="">
<P>为了使页面开发人员尽可能简单的显示警告框，让我们创建一个名为 <B>ClientSidePage</B> 的类，其中包含一个名为 <B>DisplayAlert(message)</B> 的方法。这个类将会继承 <B>Page</B> 类。想要利用这些客户端 helper 方法的页面开发人员需要使他们的代码隐藏类继承这个 <B>ClientSidePage</B> 类，而不是继承默认的 <B>Page</B> 类。以下代码显示了带有其第一个方法 <B>DisplayAlert</B> 的 <B>ClientSidePage</B> 类。</P></DIV>Public Class ClientSidePage Inherits System.Web.UI.Page Public Sub DisplayAlert(ByVal message As String) RegisterClientScriptBlock(Guid.NewGuid().ToString(), _ "&lt;script language=""JavaScript""&gt;" &amp; GetAlertScript(message) &amp; "&lt;/script&gt;") End Sub Public Function GetAlertScript(ByVal message As String) As String Return "alert('" &amp; message.Replace("'", "\'") &amp; "');" End Function End Class 
<DIV id="">
<P>请注意，这个类派生自 <B>System.Web.UI.Page</B> 类。<B>DisplayAlert</B> 方法只是使用 <B>RegisterClientScriptBlock</B> 方法，在警告框中显示提供的 <I>message</I>。由于这个方法可能会由单个页面多次调用，每个调用将使用其密钥的 GUID（是“全局唯一标识符”的首字母缩写）。传递到 <B>alert</B> 函数的字符串会使用撇号分隔，<I>message</I> 中的任意撇号都必须进行转义（JavaScript 将撇号转义为 \'）。 </P></DIV>
<DIV id="">
<P>要将这段代码用于 ASP.NET Web 应用程序中，您需要将新类添加到 ASP.NET 应用程序中。在 Visual Studio .NET 中，右键单击解决方案资源管理器中的 ASP.NET Web 应用程序项目名，然后选择添加新类。然后，剪切上述代码并将其粘贴到该类中。接下来，在要利用该代码的 ASP.NET 网页中，您需要修改代码隐藏类，以便它从 <B>ClientSidePage</B> 类而不是从 <B>Page</B> 中继承。以下代码显示了派生自 <B>ClientSidePage</B> 并使用 <B>DisplayAlert</B> 方法的示例代码隐藏类。</P></DIV>Public Class WebForm1 Inherits ClientSidePage Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load DisplayAlert("Hello, World!") End Sub ... End Class 
<DIV id="">
<P>请注意，<B>ClientSidePage</B> 类不仅具有可以生成完整客户端 &lt;<B>script</B>&gt; 元素的 <B>DisplayAlert</B> 方法，还具有可以返回客户端脚本无 &lt;<B>script</B>&gt; 标记的 <B>GetAlertScript</B> 方法。第二个方法可用于您希望基于某个客户端事件显示警告的情况中。例如，如果您希望在特定文本框接收到焦点的任意时间显示警告，可以将以下代码添加到服务器端代码隐藏类中：</P></DIV>TextBoxControlID.Attributes("onfocus") = GetAlertScript(message) </DIV>
<DIV id="">将焦点设置为页面加载时的窗体字段 
<DIV id="">
<P>您是否注意到当访问 Google 时，焦点自动设置在搜索文本框呢？这一点小的“功能”使得搜索 Google 更快 － 在访问 Google 时您不必再花费时间移动鼠标，然后单击文本框。更确切的说，您只需在页面加载时键入即可。将焦点设置到窗体字段（可以是文本框、单选按钮、复选框或下拉列表）只要求几行客户端 JavaScript 代码。让我们将方法添加到 <B>ClientSidePage</B> 类，该类将在页面加载时自动向指定的 Web 控件中添加焦点。这种方法需要发出如下所示的客户端脚本：</P></DIV>&lt;script language="JavaScript"&gt; function CSP_focus(id) { var o = document.getElementById(id); if (o != null) o.focus(); } &lt;/script&gt; ... Form fields ... &lt;input type="..." id="id of element to focus" ... /&gt; ... Form fields ... &lt;script language="JavaScript"&gt; CSP_focus(id of element to focus); &lt;/script&gt; 
<DIV id="">
<P>客户端函数 <B>CSP_focus</B> 接受字符串参数，窗体字段的 <B>ID</B> 被设置为焦点，并且从 DOM 中检索 HTML 元素。然后，调用检索元素的<B> focus()</B> 函数。在网页的底部，在指定所有窗体字段后，我们需要调用 <B>CSP_focus</B> 方法，该方法在想要设置焦点的窗体字段的<B> ID</B> 中传递。</P></DIV>
<DIV id="">
<P>下面的方法 <B>GiveFocus(Control)</B> 使用 <B>RegisterClientScriptBlock</B> 和 <B>RegisterStartupScript</B> 方法来生成所需要的客户端脚本。</P></DIV>Public Sub GiveFocus(ByVal c As Control) RegisterClientScriptBlock("CSP-focus-function", _ "&lt;script language=""JavaScript""&gt;" &amp; vbCrLf &amp; _ "function CSP_focus(id) {" &amp; _ " var o = document.getElementById(id); " &amp; _ "if (o != null) o.focus(); " &amp; _ "}" &amp; vbCrLf &amp; _ "&lt;/script&gt;") RegisterStartupScript("CSP-focus", _ "&lt;script language=""JavaScript""&gt;CSP_focus('" &amp; _ c.ClientID &amp; "');&lt;/script&gt;") End Sub 
<DIV id="">
<P>要从其代码隐藏类继承 <B>ClientSidePage</B> 的 ASP.NET 网页中使用 <B>GiveFocus</B> 方法，可以简单地在 <B>Page_Load</B> 事件处理程序中调用 <B>GiveFocus</B>，并传递应该在页面加载时设置其焦点的 <B>Web</B> 控件。例如，要将焦点设置为 <B>TextBox</B> Web 控件 <B>TextBoxControl</B>，请使用以下 <B>Page_Load</B> 事件处理程序：</P></DIV>Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load GiveFocus(TextBoxControl) End Sub </DIV>
<DIV id="">打开弹出窗口 
<DIV id="">
<P>尽管弹出窗口作为广告发布者的工具在 Internet 上早已臭名昭著，但是很多 Web 应用程序还是因为使用弹出窗口而得到了好处。例如，您想要某个页面在 <B>DataGrid</B> 中显示数据库项目的列表，同时带有可以编辑每个特定项目的链接。不再使用 <B>DataGrid</B> 的内联编辑功能，您可能希望在用户选择编辑 <B>DataGrid</B> 时打开弹出窗口，其中弹出窗口包含带有可编辑 <B>DataGrid</B> 字段的文本框列表。（您希望这么做的一个原因在于可能存在大量的可编辑字段，但是您只想显示 <B>DataGrid</B> 中最适当的字段，因此要消除使用 <B>DataGrid</B> 的内置编辑功能的可能性。）</P></DIV>
<DIV id="">
<P>要显示弹出窗口，请使用 JavaScript 函数 <B>window.open()</B>，它使用很多可选输入参数，其中三个密切相关的参数是： </P></DIV>• 
<DIV id="">
<P>加载弹出窗口的 URL。 </P></DIV>• 
<DIV id="">
<P>弹出窗口的字符串名称。 </P></DIV>• 
<DIV id="">
<P>弹出窗口的特性，例如高度和宽度、窗口是否可以调整大小等等。 </P></DIV>
<DIV id="">
<P><B>window.open()</B> 函数的完整讨论已经超出了本文的范围；要学习更多内容，请参阅<A href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/open_0.asp" target=_blank><FONT color=#004377>技术文档</FONT></A>。</P></DIV>
<DIV id="">
<P>与其他显示警告框的方法相似，<B>ClientSidePage</B> 类包含用于显示弹出窗口的两个方法 － 一个呈现显示窗口的自包含 &lt;<B>script</B>&gt; 块，另一个仅返回 JavaScript 脚本本身。除了打开弹出窗口的方法外，还有一组关闭当前窗口的方法。（可能会出现这样的情况，您希望以编程方式基于某些客户端或服务器端事件来关闭弹出窗口。）</P></DIV>Public Sub DisplayPopup(ByVal url As String, ByVal options As String) RegisterStartupScript(Guid.NewGuid().ToString(), _ "&lt;script language=""JavaScript""&gt;" &amp; _ GetPopupScript(url, options) &amp; _ "&lt;/script&gt;") End Sub Public Function GetPopupScript(ByVal url As String, _ ByVal options As String) As String Return "var w = window.open(""" &amp; _ url &amp; """, null, """ &amp; options &amp; """);" End Function Public Sub CloseWindow(Optional ByVal refreshParent As Boolean = False) RegisterClientScriptBlock("CSP-close-popup", _ "&lt;script language=""JavaScript""&gt;" &amp; _ GetCloseWindowScript(refreshParent) &amp; "&lt;/script&gt;") End Sub Public Function GetCloseWindowScript(Optional _ ByVal refreshParent As Boolean = False) As String Dim script As String If refreshParent Then script &amp;= "window.opener.location.reload();" End If Return "self.close();" End Function 
<DIV id="">
<P>该代码的执行示例可以在本文的代码下载中找到。同时，您还将发现一个示例网页，它具有一个在与 ASP.NET 网页相同的目录中列出文件的 <B>DataGrid</B>。这个 <B>DataGrid</B> 具有两列：显示超级链接的 TemplateColumn，当单击时打开显示所选文件内容的弹出窗口；以及该文件的名称（如图 3 所示）。 </P></DIV>
<DIV style="WIDTH: 415px"><IMG height=542 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig03.gif" width=415 border=0><BR>
<P class=figureCaption><B>图</B><B> 3.</B> 带有弹出窗口的 DataGrid</P>
<DIV class=figureRule></DIV></DIV>
<DIV id="">
<P><B>DataGrid</B> 的标记利用 <B>GetPopupScript</B> 方法，如下所示：</P></DIV>&lt;asp:DataGrid id="dgFiles" runat="server" ...&gt; &lt;Columns&gt; &lt;asp:TemplateColumn HeaderText="View"&gt; &lt;ItemTemplate&gt; &lt;a href='javascript:&lt;%# GetPopupScript("ViewFile.aspx?FileName=" &amp; DataBinder.Eval(Container.DataItem, "Name"), "scrollbars=yes,resizable=yes,width=500,height=400") %&gt;'&gt; View File&lt;/a&gt; &lt;/ItemTemplate&gt; &lt;/asp:TemplateColumn&gt; &lt;asp:BoundColumn DataField="Name" HeaderText="Filename"&gt;&lt;/asp:BoundColumn&gt; &lt;/Columns&gt; &lt;/asp:DataGrid&gt; 
<DIV id="">
<P>ASP.NET 网页 ViewFile.aspx 打开其名称在 querystring 中指定的文件并显示其内容（如图 4 所示）。</P></DIV>
<DIV style="WIDTH: 450px"><IMG height=360 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig04.gif" width=450 border=0><BR>
<P class=figureCaption><B>图</B><B> 4.</B> 在弹出窗口中显示 Web.config 的内容</P>
<DIV class=figureRule></DIV></DIV>
<DIV id="">
<P><B>注</B> 弹出窗口最适用于只有 Intranet 应用程序的情况，因为很多 Internet 用户利用某种弹出阻止软件，例如 <A href="http://toolbar.google.com/" target=_blank><FONT color=#004377>Google 工具栏</FONT></A>。实际上，利用 Microsoft Windows XP Service Pack 2，Microsoft Internet Explorer 将会在默认情况下配置为阻止弹出窗口。但是，当用户访问受信任站点或本地 Intranet 区域中的站点时，弹出窗口将仍然会出现。有关在 Windows XP Service Pack 2 中阻止 Internet Explorer 弹出窗口功能的详细信息，请务必阅读 <A href="http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx" target=_blank><FONT color=#004377>Changes to Functionality in Microsoft Windows XP Service Pack 2</FONT></A>。</P></DIV></DIV>
<DIV id="">在回发前确认 
<DIV id="">
<P>在本文的前面部分，我们研究了如何显示客户端警告框，这是带有“OK”按钮的模式对话框。JavaScript 提供被称为确认对话框的更具有交互风格的警告框。使用 <B>confirm(message) </B>函数显示确认对话框并通过 message 输入参数与“OK”和“Cancel”按钮指定显示带有文本的对话框的效果。如果用户单击“OK”，<B>confirm(message) </B>函数会返回 true；如果他们单击“Cancel”，则返回 false。</P></DIV>
<DIV id="">
<P>通常情况下，确认对话框用于确保用户在提交窗体之前希望继续。当单击 HTML 元素（例如提交按钮）提交窗体时，如果 HTML 元素触发返回 false 的客户端事件处理程序，窗体提交就被取消。通常，确认对话框用于网页中，如下所示：</P></DIV>&lt;form ...&gt; &lt;input type="submit" value="Click Me to Submit the Form" onclick="return confirm('Are you sure you want to submit this form?');" /&gt; &lt;/form&gt; 
<DIV id="">
<P>当用户单击“Click Me to Submit the Form”按钮时，他们将会看到确认对话框，询问他们是否确实希望提交该窗体（如图 5 所示）。如果用户单击“OK”，<B>confirm()</B> 将返回 true，该窗体将被提交。但是，如果他们单击“Cancel”按钮，<B>confirm()</B> 将返回 false，该窗体提交将被取消。</P></DIV>
<DIV style="WIDTH: 282px"><IMG height=119 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig05.gif" width=282 border=0><BR>
<P class=figureCaption><B>图</B><B> 5.</B> 确认 JavaScript 的结果</P>
<DIV class=figureRule></DIV></DIV>
<DIV id="">
<P>设想您具有一个 <B>DataGrid</B>带有标签为“Delete”的一列按钮。在单击该按钮时，该窗体将会回发，并且选定的记录将被删除。在此例中，您可能希望复查用户是否确实希望删除该记录。此时，要使用客户端确认对话框将会非常理想。您可以用对话框提示用户，声明如下所示的内容：“This will permanently delete the record.Are you sure you want to continue?”如果用户单击“OK”，该窗体将会回发，并且记录将被删除；如果他们单击“Cancel”，该窗体将不会回发，而且记录也不会被删除。</P></DIV>
<DIV id="">
<P>要添加在单击按钮后显示确认对话框所必需的客户端 JavaScript，请简单地使用 <B>Attributes</B> 集合来添加客户端 <B>onclick</B> 事件处理程序。具体说来，要将 <B>onclick</B> 事件处理程序代码设置为：return confirm(message);。为了提供 <B>DataGrid</B> 的 <B>ButtonColumn</B> 的这种功能，您需要在 <B>DataGrid</B> 的 <B>ItemCreated</B> 或 <B>ItemDataBound</B> 事件处理程序中以编程方式引用 <B>Button</B> 或 <B>LinkButton</B> 控件，并且在那里设置 <B>onclick</B> 属性。有关详细信息，请参阅 <A href="http://aspnet.4guysfromrolla.com/articles/090402-1.aspx" target=_blank><FONT color=#004377>http://aspnet.4guysfromrolla.com/articles/090402-1.aspx</FONT></A>。</P></DIV></DIV>
<DIV id="">确认 AutoPostBack DropDownLists 
<DIV id="">
<P>尽管通常在单击按钮时使用确认对话框，但是还可以在更改下拉列表时使用它们。例如，您可能具有一个当特定的 <B>DropDownList</B> Web 控件发生更改时会自动回发的网页。（<B>DropDownList</B> Web 控件具有一个 <B>AutoPostBack</B> 属性，如果设置为 True，只要 <B>DropDownList</B> 的选定项目发生更改就会导致窗体回发。）</P></DIV>
<DIV id="">
<P>直观地讲，您可能认为对 <B>DropDownList</B> 添加确认对话框与对 <B>Button</B> Web 控件添加这种对话框相同。也就是说，简单地将 <B>DropDownList</B> 的客户端 <B>onchange</B> 属性更改为如下内容：return confirm(...);。使用：</P></DIV>DropDownListID.Attributes("onchange") = "return confirm(...);" 
<DIV id="">
<P>遗憾的是，这并不会按期望工作，因为 <B>AutoPostBack</B><B>DropDownList</B> 的 <B>onchange</B> 属性将设置为会导致回发的 JavaScript，即对客户端 <B>__doPostBack</B> 函数的调用。当您自己借助编程方式设置 <B>onchange</B> 属性时，最后的结果是呈现的客户端 <B>onchange</B> 事件处理程序同时具有您的代码和对 <B>__doPostBack</B> 的调用：</P></DIV>&lt;select onchange="return confirm(...);__doPostBack(...);"&gt; ... &lt;/select&gt; 
<DIV id="">
<P>记住，我们确实希望发生的情况是，如果确认返回 true，就调用 <B>__doPostBack</B> 函数，因为之后页面将会被回发。通过利用 <B>Attributes</B> 集合将 <B>onchange</B> 事件设置为：if (confirm(...))，我们可以完成这一操作，而该代码会生成以下标记，该标记正是我们所希望的：</P></DIV>&lt;select onchange="if (confirm(...)) __doPostBack(...);"&gt; ... &lt;/select&gt; 
<DIV id="">
<P>乍看起来，这似乎会具有所期望的效果。如果用户从下拉列表中选择不同的项目，将会出现一个确认框。如果用户单击“OK”，该窗体将回发；如果用户单击“Cancel”，该窗体回发会暂停。尽管问题在于下拉列表维持用户选定的项目以启动下拉列表的 <B>onchange</B> 事件。例如，设想下拉列表加载正在进行选择的项目 x，然后用户选择项目 y。这将会触发下拉列表客户端 <B>onchange</B> 事件，它将会显示确认对话框。现在，设想用户点击“Cancel”－ 下拉列表将仍然选择项目 y。我们希望的是将选择转回到项目 x。</P></DIV>
<DIV id="">
<P>要实现此目的，我们需要做两件事情： </P></DIV>
<P>1.</P>
<DIV id="">
<P>编写一个“记住”选定下拉列表项目的 JavaScript 函数。 </P></DIV>
<P>2.</P>
<DIV id="">
<P>在下拉列表的客户端 onchange 事件中，如果用户单击“Cancel”，您需要将下拉列表转换回“已记住的”值。 </P></DIV>
<DIV id="">
<P>步骤 1 必须为下拉列表和函数（当页面加载时运行，并且记录下拉列表的值）创建全局脚本变量。步骤 2 要求为下拉列表的客户端 <B>onchange</B> 属性更改为如下所示内容：</P></DIV>if (!confirm(...)) resetDDLIndex(); else __doPostBack(); 
<DIV id="">
<P>其中 <B>resetDDLIndex</B> 是 JavaScript 函数，它将下拉列表选定的值返回到“已记住的”值。用于此目的的客户端脚本应该如下所示：</P></DIV>&lt;select id="ddlID" onchange="if (!confirm(...)) resetDDLIndex(); else __doPostBack(...);"&gt; ... &lt;/select&gt; &lt;script language="JavaScript"&gt; var savedDDLID = document.getElementById("ddlID").value; function resetDDLIndex() { document.getElementById("ddlID").value = savedDDLID; } &lt;/script&gt; 
<DIV id="">
<P>通过在 <B>ClientSidePage</B> 类中创建 helper 方法，这个必要的脚本可以轻松地生成。</P></DIV>Public Sub ConfirmOnChange(ByVal ddl As DropDownList, ByVal message As String) 'Register the script block If Not IsStartupScriptRegistered("CSP-ddl-onchange") Then RegisterStartupScript("CSP-ddl-onchange", _ "&lt;script language=""JavaScript""&gt;" &amp; _ "var CSP_savedDDLID = " &amp; _ document.getElementById('" &amp; _ ddl.ClientID &amp; "').value;" &amp; vbCrLf &amp; _ "function resetDDLIndex() {" &amp; vbCrLf &amp; _ " document.getElementById('" &amp; " &amp; _ " ddl.ClientID &amp; "').value = CSP_savedDDLID;" &amp; vbCrLf &amp; _ "}" &amp; vbCrLf &amp; _ "&lt;/script&gt;") End If ddl.Attributes("onchange") = _ "if (!confirm('" &amp; message.Replace("'", "\'") &amp; _ "')) resetDDLIndex(); else " End Sub 
<DIV id="">
<P>要使用这段代码，简单地调用网页上每个 <B>AutoPostBack</B><B>DropDownList</B> 的该方法，当网页上的选定项目发生更改时要在该网页上显示对话框。</P></DIV></DIV>
<DIV id="">未保存而退出时进行确认 
<DIV id="">
<P>在我所创建的大多数每个数据驱动的 Web 应用程序中，始终会有用户可以编辑数据库特定信息的特定页面。非常简单的一个示例是带有一系列 <B>TextBox</B> 和 <B>DropDownList</B> Web 控件的页面，而数据库数据填充在这些控件中。用户可以进行任何适当的修改，然后单击“Save”按钮将他们所做的更改保存到数据库。</P></DIV>
<DIV id="">
<P>当我创建这些页面时，通常会以两个 <B>Button</B> Web 控件来结束页面：“Save”按钮和“Cancel”按钮。“Save”按钮将任意更改保存回数据库，而“Cancel”按钮不保存任何更改退出页面。尽管两个按钮看起来可能是一个完美的设计，但有时用户会在他们想要单击“Save”按钮时意外地单击“Cancel”按钮，这样就会丢失了他们对数据所做的所有更改。为防止这种情况发生，可以在“Cancel”按钮上使用确认框，它只有在网页上的任意文本框或下拉列表发生更改时才会出现。也就是说，如果用户对数据进行了任意更改，然后单击“Cancel”，确认框将会提示他们是否确实要在不保存的情况下退出。（如果用户只是单击“Cancel”，而没有更改任何数据，将不会显示这样的确认框。）</P></DIV>
<DIV id="">
<P>这种用户体验可以通过少量客户端 JavaScript 来实现。基本上可以说，它需要一个 JavaScript 全局变量 <B>isDirty</B>，在初始时为 false，但只要触发窗体字段的 <B>onchange</B> 事件，它就会设置为 true。如果 <B>isDirty</B> 为 true，则还有一个显示确认对话框的 JavaScript 函数。“Cancel”按钮的 <B>onclick</B> 客户端事件处理程序限定为从该 JavaScript 函数返回结果。以下 HTML 说明了这个概念：</P></DIV>&lt;script language="JavaScript"&gt; var isDirty= false; function checkForChange(msg) { if (isDirty) return confirm(msg); else return true; } &lt;/script&gt; Name: &lt;input type="text" onchange="isDirty = true;" /&gt; &lt;input type="submit" name="btnSave" value="Save" id="btnSave" /&gt; &lt;input type="submit" name="btnCancel" value="Cancel" id="btnCancel" onclick="return checkForChange('You have made changes to the data since last saving. If you continue, you will lose these changes.');" /&gt; 
<DIV id="">
<P>可以通过将该脚本生成移动到 <B>ClientSidePage</B> 类，简单地生成这个脚本。具体说来，我们可以创建下列三个方法：</P></DIV>Protected Sub RegisterOnchangeScript() If Not IsClientScriptBlockRegistered("CSP-onchange-function") Then RegisterClientScriptBlock("CSP-onchange-function", _ "&lt;script language=""JavaScript""&gt;" &amp; _ "var isDirty= false;" &amp; vbCrLf &amp; _ "function CSP_checkForChange(msg) {" &amp; vbCrLf &amp; _ " if (isDirty) return confirm(msg); " &amp; _ "else return true;" &amp; vbCrLf &amp; _ "}" &amp; vbCrLf &amp; _ "&lt;/script&gt;") End If End Sub Public Sub MonitorChanges(ByVal c As WebControl) RegisterOnchangeScript() If TypeOf c Is CheckBox Or TypeOf c Is CheckBoxList _ Or TypeOf c Is RadioButtonList Then c.Attributes("onclick") = "isDirty = true;" Else c.Attributes("onchange") = "isDirty = true;" End If End Sub Public Sub ConfirmOnExit(ByVal c As WebControl, ByVal message As String) RegisterOnchangeScript() c.Attributes("onclick") = _ "return CSP_checkForChange('" &amp; message.Replace("'", "\'") &amp; "');" End Sub 
<DIV id="">
<P>要创建表现这个行为的网页，我们只需要将其服务器端代码隐藏类派生自 <B>ClientSidePage</B>，并且在 <B>Page_Load</B> 事件处理程序中，为需要客户端 onchange 事件的每个 Web 控件对 <B>MonitorChanges</B> 进行调用，并且为在单击时应该显示警告用户是否进行更改并退出页面的每个 <B>Button</B>、<B>LinkButton</B> 和 <B>ImageButton</B>，对 <B>ConfirmOnExit</B> 进行调用。</P></DIV>
<DIV id="">
<P><B>注</B><B>MonitorChanges</B> 方法使用 <B>onclick</B> 客户端事件，而不是用于 <B>CheckBox</B>、<B>CheckBoxList</B> 和 <B>RadioButtonList</B> Web 控件的 <B>onchange</B>。这是因为这些控件将 &lt;<B>span</B>&gt; 标记或 &lt;<B>table</B>&gt; 限制在复选框或很多复选框或单选按钮附近。在我利用 Internet Explorer 进行测试时，我发现在应用到 &lt;<B>span</B>&gt; 或 &lt;<B>table</B>&gt; 时，选中复选框或单击单选按钮并没有选择 <B>onchange</B> 事件，但是却触发了 <B>onclick</B> 事件。</P></DIV>
<DIV id="">
<P>图 6 显示了带有两个 <B>TextBox</B> Web 控件、一个 <B>DropDownList</B> Web 控件和一个 <B>CheckBox</B> Web 控件的 ASP.NET 网页示例。如下面的 <B>Page_Load</B> 事件处理程序所示，所有这些 Web 控件都会被监视所做的更改。配置“Cancel”按钮 <B>btnCancel</B>，这样如果在进行更改后单击它，将显示一个确认对话框。</P></DIV>
<DIV style="WIDTH: 374px"><IMG height=356 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig06.gif" width=374 border=0><BR>
<P class=figureCaption><B>图</B><B> 6.</B> 带有确认的对话框</P>
<DIV class=figureRule></DIV></DIV>Public Class ConfirmOnExit Inherits ClientSidePage Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load 'Specify what controls to check for changes MonitorChanges(name) MonitorChanges(age) MonitorChanges(favColor) MonitorChanges(chkSilly) ConfirmOnExit(btnCancel, _ "You have made changes to the data since last saving." &amp; _ " If you continue, you will lose these changes.") End Sub ... End Class 
<DIV id="">
<P><B>注</B>客户端 <B>onchange</B> 事件不能用于 Netscape 的旧版本中。同样，Internet Explorer 5.0 的 <B>onchange</B> 事件也具有<A href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;238391" target=_blank><FONT color=#004377>一些已报告的问题</FONT></A>（在 Internet Explorer 5.01 SP 1 中已经修复）。 </P></DIV>
<DIV id="">
<P>而且，这种方法将不会像利用 <B>DropDownList</B> Web 控件那样将 <B>AutoPostBack</B> 设置为 True，而是回发将重置 <B>isDirty</B> 的值。这个问题有很多解决方案，例如使用隐藏窗体字段，指示出回发窗体数据是否以 dirty 开始。我将实现这个操作的过程作为练习留给读者。</P></DIV></DIV>
<DIV id="">创建客户端 MessageBox 控件 
<DIV id="">
<P>由于确认对话框是一种防止意外点击的非常好的方法，可以潜在地降低到 Web 服务器的回发数量，有几种特定方案您可能希望显示确认对话框，并且能够在服务器端确定用户是否单击了“OK”或“Cancel”。（记住，对于确认对话框，如果用户单击“Cancel”，该窗体则不会回发。）而且，JavaScript 中的警告和确认框在外观上非常受限。幸运的是，客户端 VBScript 通过其 MsgBox 函数提供了更丰富的消息框体验。</P></DIV>
<DIV id="">
<P>在过去的项目中，我需要客户端模式消息框，无论单击什么按钮，它都可以引起回发。作为响应，我构建了自定义编译的 ASP.NET 服务器控件来满足这些要求。此外，客户端消息框还使用 VBScript 的 <B>MsgBox</B> 函数来提供更丰富的消息框体验。</P></DIV>
<DIV id="">
<P><B>注</B> 在 Microsoft Internet Explorer 浏览器中，VBScript 只作为客户端脚本编辑语言。要考虑到这一点，如果访问浏览器是 Internet Explorer，那么我的服务器控件只能使用 VBScript。如果是非 Internet Explorer 浏览器，则服务器端控件使用 JavaScript。</P></DIV>
<DIV id="">
<P>对这种自定义服务器控件深入的讨论可以完全保证整个文章的正确性，因此无需将重点放在控件的内部工作原理上，让我们分析如何在 ASP.NET 网页中使用 <B>MessageBox</B> 控件。（控件的完整资源以及使用该控件的示例 ASP.NET 网页都可以从本文的下载中获得。）</P></DIV>
<DIV id="">
<P>要在 ASP.NET 网页中使用 <B>MessageBox</B> 控件，首先要将 <B>MessageBox</B> 控件添加到 Visual Studio .NET 工具箱。通过右键单击工具箱、从工具箱中选择“Add/Remove Items”、然后浏览到 <B>MessageBox</B> 程序集可以实现上述任务。要将客户端消息框添加到网页，只要将其从工具箱拖动到该设计器即可。图 7 显示了 Visual Studio .NET 设计器中的 <B>MessageBox</B> 控件。</P></DIV>
<DIV style="WIDTH: 450px"><IMG height=290 alt="" src="http://www.microsoft.com/china/msdn/library/webservices/asp.net/art/clientside_fig07thumb.gif" width=450 border=0><BR>
<P class=figureCaption><B>图</B><B> 7</B>. 显示模式消息框</P>
<DIV class=figureRule></DIV></DIV>
<DIV id="">
<P><B>MessageBox</B> 类具有很多可以进行配置的属性，以调整消息框的外观： </P></DIV>• 
<DIV id="">
<P><B>Buttons</B>. 指定要显示的按钮。<B>ButtonOptions</B> 枚举中定义的选项可以为：OkOnly、OkCancel、AbortRetryIgnore、YesNoCancel、YesNo 或 RetryCancel。 </P></DIV>• 
<DIV id="">
<P><B>DisplayWhenButtonClicked</B>. 点击后将显示客户端消息框的按钮 Web 控件的 <B>ID</B>。如果希望由于点击某个特定按钮而显示消息框，请使用这个属性。 </P></DIV>• 
<DIV id="">
<P><B>Icon</B>. 显示在消息框中的图标；选项定义于 <B>IconOptions</B> 枚举中。有效的值为：Critical、Question、Exclamation 和 Information。 </P></DIV>• 
<DIV id="">
<P><B>Prompt</B>. 显示在消息框中的文本。 </P></DIV>• 
<DIV id="">
<P><B>Title</B>. 消息框的标题。 </P></DIV>
<DIV id="">
<P>一旦将 <B>MessageBox</B> 控件添加到 ASP.NET 网页，下一个挑战就是使其根据特定客户端操作进行显示。<B>DisplayWhenButtonClicked</B> 属性允许您指定页面上按钮 Web 控件的<B> ID</B>点击后将会显示消息框。另外，您还可以通过调用客户端函数 <B>mb_show(id)</B> 来显示消息框，其中 <B>ID</B> 是 <B>MessageBox</B> 控件的 <B>ID</B>。</P></DIV>
<DIV id="">
<P>不管您选择在消息框中显示什么按钮配置，当单击任意按钮时，随后就会发生回发并且触发 <B>MessageBox</B> 控件的 <B>Click</B> 事件。通过在设计器中简单地双击 <B>MessageBox</B>，可以为此事件创建一个事件处理程序。事件处理程序的第二个输入参数是类型 <B>MessageBoxClickedEventArgs</B>，它包含一个返回用户单击消息框按钮的信息的 <B>ButtonClicked</B> 属性。</P></DIV>
<DIV id="">
<P><B>MessageBox</B> 控件在如下情况下非常有用，当您希望快速为用户提供模式对话框，而不管用户的选择以及回发中的结果。要查看操作中的 <B>MessageBox</B> 控件，请签出源代码下载中的 MsgBoxDemo.aspx 页面。</P></DIV></DIV></DIV>
<DIV id="">
<DIV><A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><FONT color=#004377>返回页首</FONT></A></DIV><A name=EEAA></A>小结 
<DIV id="">
<P>本文一开始就研究了网页中客户端脚本的常见使用，然后转向分析将客户端脚本插入到 ASP.NET 网页中的方法和技术。正如我们看到的那样，<B>Page</B> 类包含很多旨在借助编程方式从服务器端代码隐藏类插入客户端脚本块的方法。这些方法也常用于自定义编译的服务器控件，请参阅我以前文章中的讨论： <A href="http://msdn.microsoft.com/library/en-us/dnaspp/html/aspnet-injectclientsidesc.asp" target=_blank><FONT color=#004377>Injecting Client-Side Script from an ASP.NET Server Control</FONT></A>.</P></DIV>
<DIV id="">
<P>除了添加脚本块外，客户端功能通常必须与由某些 HTML 元素引发的客户端事件结合在一起。要借助编程方式通过服务器端代码隐藏类指定 Web 控件的客户端事件处理程序，请使用 <B>Attributes</B> 集合，它可用作所有 Web 控件的属性。</P></DIV>
<DIV id="">
<P>本文的后半部分应用了前半部分中涉及的内容，显示了如何在 ASP.NET 网页中实现常用客户端功能。我们看到了如何扩展 <B>Page</B> 类，这样我们可以利用代码隐藏类轻松地显示警告框、将页面加载上的焦点设置到特定 Web 控件、如何显示弹出窗口以及如何显示确认对话框。我们还研究了创建自定义服务器控件，它使用 VBScript 来提供更丰富的客户端消息框用户体验，而且无需考虑单击按钮就可以导致回发。</P></DIV>
<DIV id="">
<P>祝大家编程愉快！</P></DIV>
<DIV id="">特别感谢... 
<DIV id="">
<P>在我将文章提交给 MSDN 编辑之前，有很多志愿者帮助我对本文进行校对并为本文的内容、语法和目的提供了反馈。本文校对过程中的主要贡献者包括 <A href="http://www.ipattern.com/simpleblog/" target=_blank><FONT color=#004377>Maxim Karpov</FONT></A>、<A href="http://www.blackbeltsolutions.com/" target=_blank><FONT color=#004377>Carlos Santos</FONT></A>、<A href="http://aspnetresources.com/blog/default.aspx" target=_blank><FONT color=#004377>Milan Negovan</FONT></A> 和 Carl Lambrecht。如果您有兴趣加入到不断增长的校对人员中，请给我发邮件 <A href="mailto:mitchell@4guysfromrolla.com" target=_blank><FONT color=#004377>mitchell@4guysfromrolla.com</FONT></A>。 </P></DIV></DIV></DIV>
<DIV id="">
<DIV><A href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><IMG height=9 alt=返回页首 src="http://www.microsoft.com/library/gallery/templates/MNP2.Common/images/arrow_px_up.gif" width=7 border=0></A><A class=topOfPage href="http://www.microsoft.com/china/msdn/library/webservices/asp.net/WorkwithClientSideScript.mspx#top"><FONT color=#004377>返回页首</FONT></A></DIV><A name=EDAA></A>相关书籍 • 
<DIV id="">
<P><A href="http://shopping.msn.com/search/detail.aspx?pcId=12175&amp;prodId=1540110&amp;ptnrid=141&amp;ptnrdata=0" target=_blank><FONT color=#004377>ASP.NET Data Web Controls Kick Start </FONT></A></P></DIV>• 
<DIV id="">
<P><A href="http://shopping.msn.com/search/detail.aspx?pcId=12237&amp;prodId=734042&amp;ptnrid=141&amp;ptnrdata=0" target=_blank><FONT color=#004377>ASP. NET: Tips, Tutorials, &amp; Code </FONT></A></P></DIV>• 
<DIV id="">
<P><A href="http://shopping.msn.com/search/detail.aspx?pcId=4650&amp;prodId=1627167&amp;ptnrid=141&amp;ptnrdata=0" target=_blank><FONT color=#004377>Programming Microsoft ASP.NET </FONT></A></P></DIV></DIV>
<DIV id="">
<P><B>关于作者</B><B></B></P></DIV>
<DIV id="">
<P>Scott Mitchell 著有五本书，他是 4GuysFromRolla.com 网站的创始人，过去五年来一直从事 Microsoft Web 技术方面的研究。Scott 是一位独立的顾问、培训师和作家。您可以通过 <A href="mailto:mitchell@4guysfromrolla.com" target=_blank><FONT color=#004377>mitchell@4guysfromrolla.com</FONT></A> 与作者进行联络，或者通过作者的 blog 进行联络，其网址是：<A href="http://scottonwriting.net/" target=_blank><FONT color=#004377>http://ScottOnWriting.NET</FONT></A>。</P></DIV>
<DIV id="">
<P><A href="http://msdn.microsoft.com/asp.net/using/building/web/default.aspx?pull=/library/en-us/dnaspp/html/ClientSideScript.asp" target=_blank><FONT color=#004377>转到原英文页面</FONT></A></P></DIV>
<P></P></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 border=0>
<TBODY></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/songfei/aggbug/23037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 21:16 <a href="http://www.blogjava.net/songfei/articles/23037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Asp.net中如何关闭网页,另外如何使文本框获得焦点(只适用于C#)</title><link>http://www.blogjava.net/songfei/articles/22980.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 06:52:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22980.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22980.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22980.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22980.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22980.html</trackback:ping><description><![CDATA[<STRONG><SPAN id=dgfiList__ctl5_Title>补充一下 开始先导入 nam......</SPAN> <BR></STRONG><SPAN id=dgfiList__ctl5_Body>补充一下&nbsp;开始先导入 <BR>namespace <BR>using&nbsp;System.Text; <BR>using&nbsp;System.Web.UI; <BR><BR>在web&nbsp;页面中 <BR>通过调用Focus类中的方法实现获取焦点的目的&nbsp;可以放在Page_Load(，）中实现&nbsp;也可以在Button_click事件中实现 <BR>我用的是Button_Click时间 <BR>代码如下 <BR>//TextBox1是要获得焦点的控件的ID <BR>Focus.SetEnterControl(this.TextBox1); <BR>Focus.SetFocus(TextBox1.Page,"TextBox1"); <BR><BR>好了&nbsp;你自己试试看吧 <BR><BR><BR><STRONG><SPAN id=dgfiList__ctl4_Title>关闭网页调用javascrip......</SPAN> <BR></STRONG><SPAN id=dgfiList__ctl4_Body>关闭网页调用javascript <BR>&lt;script&nbsp;lang="text/javascript"&gt; <BR>window.close(); <BR>&lt;/script&gt; <BR>获得焦点&nbsp;在C＃中新建一个类 <BR>例如： <BR>sing&nbsp;System; <BR>using&nbsp;System.Text; <BR>using&nbsp;System.Web; <BR>using&nbsp;System.Web.UI; <BR>namespace&nbsp;Application <BR>{ <BR>///&nbsp;&lt;summary&gt; <BR>///&nbsp;获取焦点类 <BR>///&nbsp;&lt;/summary&gt; <BR>public&nbsp;class&nbsp;Focus <BR>{ <BR>public&nbsp;Focus() <BR>{ <BR>} <BR>//设置成一个静态的方法，这样在使用的时候不用创建一个实例对象，直接采用Focus.SetFocus(this,&nbsp;"Button2")的形式进行调用。 <BR>public&nbsp;static&nbsp;void&nbsp;SetFocus(System.Web.UI.Page&nbsp;page,&nbsp;String&nbsp;m_focusedControl) <BR>{ <BR>//如果控件名称为空，则返回 <BR>if(m_focusedControl&nbsp;==&nbsp;"") <BR>return; <BR>//添加脚本以声明函数 <BR>StringBuilder&nbsp;sb&nbsp;=&nbsp;new&nbsp;StringBuilder(""); <BR>sb.Append("&lt;script&nbsp;language=javascript&gt;"); <BR>sb.Append("function&nbsp;"); <BR>sb.Append("setFocusFunctionName"); <BR>sb.Append("(ctl)&nbsp;{"); <BR>sb.Append("if(document.forms[0][ctl]&nbsp;!=&nbsp;null)&nbsp;");//如果不为空，则设置焦点，这里调用的Javascript里面的方法 <BR>sb.Append("&nbsp;document.forms[0][ctl].focus();"&nbsp;); <BR>sb.Append("}"); <BR><BR>//添加脚本以调用函数 <BR>sb.Append("setFocusFunctionName"); <BR>sb.Append("('"); <BR>sb.Append(m_focusedControl); <BR>sb.Append("');"); <BR>sb.Append("&lt;/"); <BR>sb.Append("script&gt;"); <BR><BR>if&nbsp;(!page.IsStartupScriptRegistered("SetFocusScriptName"))&nbsp; <BR>page.RegisterStartupScript("SetFocusScriptName",&nbsp;sb.ToString());//将这段javascript代码写到页面中去 <BR>} <BR>///&nbsp;&lt;summary&gt;&nbsp; <BR>///&nbsp;设置在页面回车时触发事件的控件&nbsp; <BR>///&nbsp;&lt;/summary&gt;&nbsp; <BR>///&nbsp;&lt;param&nbsp;name="Ctrl"&gt;将触发事件的控件对象&lt;/param&gt;&nbsp; <BR>public&nbsp;static&nbsp;void&nbsp;SetEnterControl(System.Web.UI.Control&nbsp;Ctrl)&nbsp; <BR>{&nbsp; <BR>Page&nbsp;mPage&nbsp;=&nbsp;Ctrl.Page;&nbsp; <BR>string&nbsp;mScript;&nbsp; <BR>mScript&nbsp;=&nbsp;@"&lt;script&nbsp;language=""javascript""&gt;&nbsp; <BR>function&nbsp;document.onkeydown()&nbsp; <BR>{&nbsp; <BR>var&nbsp;e&nbsp;=&nbsp;event.srcElement;&nbsp; <BR>var&nbsp;k&nbsp;=&nbsp;event.keyCode;&nbsp; <BR>if&nbsp;(k&nbsp;==&nbsp;13&nbsp;&amp;&amp;&nbsp;e.type&nbsp;!=&nbsp;""textarea"")&nbsp; <BR>{&nbsp; <BR>document.all."&nbsp;+&nbsp;Ctrl.ClientID&nbsp;+&nbsp;@".click();&nbsp; <BR>event.cancelBubble&nbsp;=&nbsp;true;&nbsp; <BR>event.returnValue&nbsp;=&nbsp;false;&nbsp; <BR>}&nbsp; <BR>}&nbsp; <BR>&lt;/script&gt;";&nbsp; <BR>if(!mPage.IsClientScriptBlockRegistered("SetEnterControl"))&nbsp; <BR>mPage.RegisterClientScriptBlock("SetEnterControl",mScript);&nbsp; <BR>} <BR>} <BR>} <BR><BR>实际上就是在codebehide&nbsp;调用javascript&nbsp;来袮补C＃&nbsp;中不能获得焦点不足 <BR>请多指教啊&nbsp;&nbsp;多多交流啊</SPAN> <BR></SPAN><img src ="http://www.blogjava.net/songfei/aggbug/22980.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 14:52 <a href="http://www.blogjava.net/songfei/articles/22980.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Control study -&gt; Drag拖放事件示例   </title><link>http://www.blogjava.net/songfei/articles/22976.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 06:25:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22976.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22976.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22976.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22976.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22976.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>&nbsp;
<P>(一).功能描述</P>
<P>&nbsp;&nbsp; 涉及到DragEnter DragDrop DragLeave DragOver QueryContinueDrag事件用法的一个例子</P>
<P>(二).代码</P>
<P>using System;<BR>using System.Drawing;<BR>using System.Collections;<BR>using System.ComponentModel;<BR>using System.Windows.Forms;<BR>using System.Data;</P>
<P>namespace 拖放数据操作_按键事件_<BR>{<BR>&nbsp;/// &lt;summary&gt;<BR>&nbsp;/// Form1 的摘要说明。<BR>&nbsp;/// &lt;/summary&gt;<BR>&nbsp;public class Form1 : System.Windows.Forms.Form<BR>&nbsp;{<BR>&nbsp;&nbsp;private System.Windows.Forms.Button button1;<BR>&nbsp;&nbsp;private System.Windows.Forms.TextBox textBox1;<BR>&nbsp;&nbsp;/// &lt;summary&gt;<BR>&nbsp;&nbsp;/// 必需的设计器变量。<BR>&nbsp;&nbsp;/// &lt;/summary&gt;<BR>&nbsp;&nbsp;private System.ComponentModel.Container components = null;</P>
<P>&nbsp;&nbsp;public Form1()<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;//<BR>&nbsp;&nbsp;&nbsp;// Windows 窗体设计器支持所必需的<BR>&nbsp;&nbsp;&nbsp;//<BR>&nbsp;&nbsp;&nbsp;InitializeComponent();</P>
<P>&nbsp;&nbsp;&nbsp;//<BR>&nbsp;&nbsp;&nbsp;// TODO: 在 InitializeComponent 调用后添加任何构造函数代码<BR>&nbsp;&nbsp;&nbsp;//<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;/// &lt;summary&gt;<BR>&nbsp;&nbsp;/// 清理所有正在使用的资源。<BR>&nbsp;&nbsp;/// &lt;/summary&gt;<BR>&nbsp;&nbsp;protected override void Dispose( bool disposing )<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if( disposing )<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if (components != null) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;components.Dispose();<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;base.Dispose( disposing );<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;#region Windows 窗体设计器生成的代码<BR>&nbsp;&nbsp;/// &lt;summary&gt;<BR>&nbsp;&nbsp;/// 设计器支持所需的方法 - 不要使用代码编辑器修改<BR>&nbsp;&nbsp;/// 此方法的内容。<BR>&nbsp;&nbsp;/// &lt;/summary&gt;<BR>&nbsp;&nbsp;private void InitializeComponent()<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;this.button1 = new System.Windows.Forms.Button();<BR>&nbsp;&nbsp;&nbsp;this.textBox1 = new System.Windows.Forms.TextBox();<BR>&nbsp;&nbsp;&nbsp;this.SuspendLayout();<BR>&nbsp;&nbsp;&nbsp;// <BR>&nbsp;&nbsp;&nbsp;// button1<BR>&nbsp;&nbsp;&nbsp;// <BR>&nbsp;&nbsp;&nbsp;this.button1.Location = new System.Drawing.Point(112, 72);<BR>&nbsp;&nbsp;&nbsp;this.button1.Name = "button1";<BR>&nbsp;&nbsp;&nbsp;this.button1.TabIndex = 0;<BR>&nbsp;&nbsp;&nbsp;this.button1.Text = "button1";<BR>&nbsp;&nbsp;&nbsp;this.button1.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.button1_QueryContinueDrag);<BR>&nbsp;&nbsp;&nbsp;this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.button1_MouseDown);<BR>&nbsp;&nbsp;&nbsp;// <BR>&nbsp;&nbsp;&nbsp;// textBox1<BR>&nbsp;&nbsp;&nbsp;// <BR>&nbsp;&nbsp;&nbsp;this.textBox1.AccessibleDescription = "aaaaa";<BR>&nbsp;&nbsp;&nbsp;this.textBox1.AccessibleName = "bbbbbb";<BR>&nbsp;&nbsp;&nbsp;this.textBox1.AllowDrop = true;<BR>&nbsp;&nbsp;&nbsp;this.textBox1.Location = new System.Drawing.Point(64, 160);<BR>&nbsp;&nbsp;&nbsp;this.textBox1.Multiline = true;<BR>&nbsp;&nbsp;&nbsp;this.textBox1.Name = "textBox1";<BR>&nbsp;&nbsp;&nbsp;this.textBox1.Size = new System.Drawing.Size(168, 48);<BR>&nbsp;&nbsp;&nbsp;this.textBox1.TabIndex = 1;<BR>&nbsp;&nbsp;&nbsp;this.textBox1.Text = "";<BR>&nbsp;&nbsp;&nbsp;this.textBox1.DragOver += new System.Windows.Forms.DragEventHandler(this.textBox1_DragOver);<BR>&nbsp;&nbsp;&nbsp;this.textBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.textBox1_DragDrop);<BR>&nbsp;&nbsp;&nbsp;this.textBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.textBox1_DragEnter);<BR>&nbsp;&nbsp;&nbsp;this.textBox1.DragLeave += new System.EventHandler(this.textBox1_DragLeave);<BR>&nbsp;&nbsp;&nbsp;// <BR>&nbsp;&nbsp;&nbsp;// Form1<BR>&nbsp;&nbsp;&nbsp;// <BR>&nbsp;&nbsp;&nbsp;this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);<BR>&nbsp;&nbsp;&nbsp;this.ClientSize = new System.Drawing.Size(292, 266);<BR>&nbsp;&nbsp;&nbsp;this.Controls.Add(this.textBox1);<BR>&nbsp;&nbsp;&nbsp;this.Controls.Add(this.button1);<BR>&nbsp;&nbsp;&nbsp;this.Name = "Form1";<BR>&nbsp;&nbsp;&nbsp;this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;<BR>&nbsp;&nbsp;&nbsp;this.Text = "Form1";<BR>&nbsp;&nbsp;&nbsp;this.ResumeLayout(false);</P>
<P>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;#endregion</P>
<P>&nbsp;&nbsp;/// &lt;summary&gt;<BR>&nbsp;&nbsp;/// 应用程序的主入口点。<BR>&nbsp;&nbsp;/// &lt;/summary&gt;<BR>&nbsp;&nbsp;[STAThread]<BR>&nbsp;&nbsp;static void Main() <BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;Application.Run(new Form1());<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;private void button1_QueryContinueDrag(object sender, System.Windows.Forms.QueryContinueDragEventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if(e.EscapePressed)<BR>&nbsp;&nbsp;&nbsp;&nbsp;e.Action=DragAction.Cancel;<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;private void button1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;button1.DoDragDrop(button1.Text,DragDropEffects.Copy|DragDropEffects.Move);<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;private void textBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if(e.Data.GetDataPresent(DataFormats.Text))<BR>&nbsp;&nbsp;&nbsp;&nbsp;e.Effect=DragDropEffects.Copy;<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;&nbsp;e.Effect=DragDropEffects.None;<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;private void textBox1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;//使用KeyState属性<BR>&nbsp;&nbsp;&nbsp;if((e.KeyState&amp;(1&lt;&lt;3))!=0)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;if((e.AllowedEffect&amp;DragDropEffects.Copy)!=0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.Effect=DragDropEffects.Copy;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textBox1.Text=e.Data.GetData(DataFormats.Text).ToString();<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;else<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;e.Effect=DragDropEffects.Move;<BR>&nbsp;&nbsp;&nbsp;&nbsp;textBox1.Text=e.Data.GetData(DataFormats.Text).ToString();<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;private void textBox1_DragLeave(object sender, System.EventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;textBox1.Text="执行 DragLeave";<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp;private void textBox1_DragOver(object sender, System.Windows.Forms.DragEventArgs e)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;textBox1.Text="执行 DragOver";<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>}<BR>&nbsp;</P></SPAN><img src ="http://www.blogjava.net/songfei/aggbug/22976.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 14:25 <a href="http://www.blogjava.net/songfei/articles/22976.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#+ASP.NET+Oracle时积累的备忘点滴之二 </title><link>http://www.blogjava.net/songfei/articles/22974.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22974.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22974.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22974.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22974.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 1、加入站点计数：&nbsp;&nbsp; 在Globalv.asax.cs中加入&nbsp;protected void Application_Start(Object sender, EventArgs e)&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;Application["GlobalCounter"]=0;&...&nbsp;&nbsp;<a href='http://www.blogjava.net/songfei/articles/22974.html'>阅读全文</a><img src ="http://www.blogjava.net/songfei/aggbug/22974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 14:18 <a href="http://www.blogjava.net/songfei/articles/22974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达的写法</title><link>http://www.blogjava.net/songfei/articles/22973.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 06:15:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22973.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22973.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22973.html</trackback:ping><description><![CDATA[<BR>正则表达的写法是： <BR>
<DIV 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: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<DIV><IMG height=16 alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" width=11 align=top><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">bool</SPAN><SPAN style="COLOR: #000000">&nbsp;IsNumeric(</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;str)&nbsp; <BR></SPAN><SPAN id=Codehighlighter1_35_171_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></SPAN><SPAN id=Codehighlighter1_35_171_Open_Text><SPAN style="COLOR: #000000">{&nbsp;&nbsp; <BR>&nbsp;&nbsp; System.Text.RegularExpressions.Regex&nbsp;reg1&nbsp; <BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;System.Text.RegularExpressions.Regex(</SPAN><SPAN style="COLOR: #000000">@"</SPAN><SPAN style="COLOR: #000000">^[-]?\d+[.]?\d*$</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);&nbsp;&nbsp; <BR>&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;reg1.IsMatch(str);&nbsp; <BR>}</SPAN></SPAN><SPAN style="COLOR: #000000">&nbsp; <BR><IMG height=16 alt="" src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" width=11 align=top></SPAN> </DIV></DIV><BR><img src ="http://www.blogjava.net/songfei/aggbug/22973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 14:15 <a href="http://www.blogjava.net/songfei/articles/22973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在.NET中获取一台电脑名，IP地址及当前用户名</title><link>http://www.blogjava.net/songfei/articles/22972.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 06:09:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22972.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22972.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22972.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22972.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22972.html</trackback:ping><description><![CDATA[<FONT color=#000000>　在.NET中获取一台电脑名，IP地址及当前用户名是非常简单，以下是我常用的几种方法,如果大家还有其他好的方法，可以回复一起整理： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　1. 在ASP.NET中专用属性： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　获取服务器电脑名：Page.Server.ManchineName <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　获取用户信息：Page.User <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　获取客户端电脑名：Page.Request.UserHostName <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　获取客户端电脑IP：Page.Request.UserHostAddress <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　2. 在网络编程中的通用方法： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　获取当前电脑名：static System.Net.Dns.GetHostName() <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　根据电脑名取出全部IP地址：static System.Net.Dns.Resolve(电脑名).AddressList <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　也可根据IP地址取出电脑名：static System.Net.Dns.Resolve(IP地址).HostName <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　3. 系统环境类的通用属性： <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　当前电脑名：static System.Environment.MachineName <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　当前电脑所属网域：static System.Environment.UserDomainName <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 　　当前电脑用户：static System.Environment.UserName</FONT>
<P><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 举例子来说明:</FONT></P>
<P><FONT color=#000000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using System.Net; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private void ButtonIP_Click(object sender, System.EventArgs e) <BR>&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; System.Net.IPAddress[] addressList = Dns.GetHostByName(Dns.GetHostName()).AddressList; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; if (addressList.Length&gt;1) <BR>&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; TextLIP.Text = addressList[0].ToString(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TextSIP.Text = addressList[1].ToString(); <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; else <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;&nbsp; TextLIP.Text = addressList[0].ToString(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TextSIP.Text = "没有可用的连接"; <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; }<BR></FONT></P><img src ="http://www.blogjava.net/songfei/aggbug/22972.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 14:09 <a href="http://www.blogjava.net/songfei/articles/22972.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> ADO.NET 2.0 Dataset和Datatable 新功能新特性     </title><link>http://www.blogjava.net/songfei/articles/22971.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 06:05:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22971.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22971.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22971.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22971.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22971.html</trackback:ping><description><![CDATA[<P>1.新的索引引擎更快的执行效率<BR>&nbsp;&nbsp; 下面这段代码在2003中需要157秒，在2005中只要11秒就可以完成：<BR></P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">DataSet&nbsp;ds&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataSet();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds.Tables.Add(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">BigTable</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds.Tables[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">].Columns.Add(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ID</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;Type.GetType(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">System.Int32</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">));<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds.Tables[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">].Columns[</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ID</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">].Unique&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds.Tables[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">].Columns.Add(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Value</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;Type.GetType(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">System.Int32</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">));<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cursor.Current&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Cursors.WaitCursor;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;datBegin&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;DateTime.Now;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Random&nbsp;rand&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Random();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;i,&nbsp;intValue;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataRow&nbsp;dr;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(i&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">;&nbsp;i&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">500000</SPAN><SPAN style="COLOR: #000000">;&nbsp;i</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)<BR><IMG id=Codehighlighter1_519_842_Open_Image onclick="this.style.display='none'; Codehighlighter1_519_842_Open_Text.style.display='none'; Codehighlighter1_519_842_Closed_Image.style.display='inline'; Codehighlighter1_519_842_Closed_Text.style.display='inline';" alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><IMG id=Codehighlighter1_519_842_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_519_842_Closed_Text.style.display='none'; Codehighlighter1_519_842_Open_Image.style.display='inline'; Codehighlighter1_519_842_Open_Text.style.display='inline';" alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN id=Codehighlighter1_519_842_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG alt="" src="http://www.cnblogs.com/Images/dot.gif"></SPAN><SPAN id=Codehighlighter1_519_842_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">try</SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_557_802_Open_Image onclick="this.style.display='none'; Codehighlighter1_557_802_Open_Text.style.display='none'; Codehighlighter1_557_802_Closed_Image.style.display='inline'; Codehighlighter1_557_802_Closed_Text.style.display='inline';" alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_557_802_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_557_802_Closed_Text.style.display='none'; Codehighlighter1_557_802_Open_Image.style.display='inline'; Codehighlighter1_557_802_Open_Text.style.display='inline';" alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN id=Codehighlighter1_557_802_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG alt="" src="http://www.cnblogs.com/Images/dot.gif"></SPAN><SPAN id=Codehighlighter1_557_802_Open_Text><SPAN style="COLOR: #000000">{<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intValue&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;rand.Next();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;ds.Tables[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">].NewRow();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dr[</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">ID</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;intValue;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dr[</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Value</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">]&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;intValue;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ds.Tables[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">].Rows.Add(dr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG id=Codehighlighter1_826_828_Open_Image onclick="this.style.display='none'; Codehighlighter1_826_828_Open_Text.style.display='none'; Codehighlighter1_826_828_Closed_Image.style.display='inline'; Codehighlighter1_826_828_Closed_Text.style.display='inline';" alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><IMG id=Codehighlighter1_826_828_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_826_828_Closed_Text.style.display='none'; Codehighlighter1_826_828_Open_Image.style.display='inline'; Codehighlighter1_826_828_Open_Text.style.display='inline';" alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">catch</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN id=Codehighlighter1_826_828_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><IMG alt="" src="http://www.cnblogs.com/Images/dot.gif"></SPAN><SPAN id=Codehighlighter1_826_828_Open_Text><SPAN style="COLOR: #000000">{&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cursor.Current&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Cursors.Default;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Elapsed&nbsp;Time:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;(DateTime.Now&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;datBegin).Seconds.ToString());<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">count&nbsp;=&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;ds.Tables[</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">].Rows.Count.ToString());<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top></SPAN></DIV>2.Dataset可以序列化为二进制文件<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;connstr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">server=(local);database=northwind;integrated&nbsp;security=true;async=true</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataSet&nbsp;ds&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataSet();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlDataAdapter&nbsp;dadpt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;SqlDataAdapter(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;*&nbsp;from&nbsp;[order&nbsp;details]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;connstr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dadpt.Fill(ds);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter&nbsp;bf&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;BinaryFormatter();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileStream&nbsp;fs&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;FileStream(</SPAN><SPAN style="COLOR: #000000">@"</SPAN><SPAN style="COLOR: #000000">c:\xml1.txt</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,FileMode.OpenOrCreate);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><SPAN style="COLOR: red"><SPAN style="COLOR: #000000"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="COLOR: #ff0000; BACKGROUND-COLOR: #ff0000"><SPAN style="COLOR: #000000">ds.RemotingFormat&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;SerializationFormat.Binary; </SPAN></SPAN></SPAN></SPAN></SPAN><SPAN style="COLOR: #000000"><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bf.Serialize(fs,ds);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN></DIV>3.更独立的Datatable<BR>&nbsp; DataTable Write XML 
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;connstr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">server=(local);database=northwind;integrated&nbsp;security=true;async=true</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlDataAdapter&nbsp;dadpt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;SqlDataAdapter(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;*&nbsp;from&nbsp;[order&nbsp;details]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;connstr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable&nbsp;dt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataTable(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Customer</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dadpt.Fill(dt);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt.WriteXml(</SPAN><SPAN style="COLOR: #000000">@"</SPAN><SPAN style="COLOR: #000000">c:\DataTable.xml</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #0000ff">true</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt.WriteXmlSchema(</SPAN><SPAN style="COLOR: #000000">@"</SPAN><SPAN style="COLOR: #000000">c:\DataTableSchema.xml</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);</SPAN></DIV>&nbsp;&nbsp; DataTable Read XML<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;StreamReader&nbsp;sr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;StreamReader(</SPAN><SPAN style="COLOR: #000000">@"</SPAN><SPAN style="COLOR: #000000">C:\DataTableSchema.xml</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable&nbsp;dt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataTable();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt.ReadXmlSchema(sr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt.ReadXml(</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;StreamReader(</SPAN><SPAN style="COLOR: #000000">@"</SPAN><SPAN style="COLOR: #000000">c:\dataTable.xml</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">));<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.dataGridView1.DataSource&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;dt;</SPAN></DIV>&nbsp;&nbsp;&nbsp; DataTable Merge<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;connstr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">server=(local);database=northwind;integrated&nbsp;security=true;async=true</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlDataAdapter&nbsp;dadpt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;SqlDataAdapter(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;*&nbsp;from&nbsp;customers</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;connstr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable&nbsp;dt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataTable(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Customer</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dadpt.Fill(dt);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlDataAdapter&nbsp;dadpt1&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;SqlDataAdapter(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;*&nbsp;from&nbsp;customers</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;connstr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable&nbsp;dt1&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataTable(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Customer1</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dadpt1.Fill(dt1);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt.Merge(dt1);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.dataGridView1.DataSource&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;dt;</SPAN></DIV>&nbsp; DataTable Load DataReader<BR>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">string</SPAN><SPAN style="COLOR: #000000">&nbsp;connstr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">server=(local);database=northwind;integrated&nbsp;security=true;async=true</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">;<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlConnection&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;SqlConnection(connstr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.Open();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlCommand&nbsp;cmd&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;SqlCommand(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">select&nbsp;*&nbsp;from&nbsp;[order&nbsp;details]</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;conn);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SqlDataReader&nbsp;dr&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;cmd.ExecuteReader();<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable&nbsp;dt&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;DataTable(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">Customer</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dt.Load(dr);<BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top><BR><IMG alt="" src="http://ghd258.cnblogs.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">this</SPAN><SPAN style="COLOR: #000000">.dataGridView1.DataSource&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;dt;</SPAN></DIV><img src ="http://www.blogjava.net/songfei/aggbug/22971.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 14:05 <a href="http://www.blogjava.net/songfei/articles/22971.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET程序中常用代码汇总</title><link>http://www.blogjava.net/songfei/articles/22970.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 05:56:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22970.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22970.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22970.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22970.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;/**////&nbsp;&lt;summary&gt;&nbsp;&nbsp;///&nbsp;名称：IsNumberic&nbsp;&nbsp;///&nbsp;功能：判断输入的是否是数字&nbsp;&nbsp;///&nbsp;参数：string&nbsp;oText：源文本&nbsp;&nbsp;///&nbsp;返回值：　bool&nbsp;true:是　false:否&nb...&nbsp;&nbsp;<a href='http://www.blogjava.net/songfei/articles/22970.html'>阅读全文</a><img src ="http://www.blogjava.net/songfei/aggbug/22970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 13:56 <a href="http://www.blogjava.net/songfei/articles/22970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>操作Excel</title><link>http://www.blogjava.net/songfei/articles/22968.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 05:51:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22968.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22968.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22968.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22968.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>&nbsp;
<P>(一).内容</P>
<BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px">
<P>&nbsp;&nbsp; 在操作Excel的过程中遇到了一些问题. 比如： 访问Com组件权限，无法读取Excel等<BR>&nbsp;&nbsp; 文章描述了怎样双向操作(读取和生成)Excel文件，以及怎样解决遇到的问题!</P></BLOCKQUOTE>
<P>(二).代码<BR>&nbsp;&nbsp; 开始时用了下面两个方法进行生成和读取 Excel:<BR>&nbsp;&nbsp; 1.生成Excel文件方法一:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ' &lt;summary&gt;<BR>&nbsp;&nbsp;&nbsp; '&nbsp; 下载Excel方法1(用流实现)<BR>&nbsp;&nbsp;&nbsp; ' &lt;/summary&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;param name="dt"&gt;要转换为Excel文件的表&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;param name="page"&gt;页面Page对象,用法: 将me.Page传递过来即可&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; Public Sub DownLoadExcelToClient1(ByVal dt As DataTable, ByVal FileName As String)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim resp As HttpResponse<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resp = Page.Response<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resp.ContentEncoding = System.Text.Encoding.Default </P>
<P>'System.Text.Encoding.GetEncoding("GB2312")<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim colHeaders As String = "", ls_item = ""<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim i As Int16 = 0</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '取得数据表各列标题，各标题之间以\t分割，最后一个列标题后加回车符 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For i = 0 To dt.Columns.Count - 2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colHeaders += dt.Columns(i).Caption.ToString() &amp; Chr(9)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colHeaders += dt.Columns(i).Caption.ToString() &amp; Chr(13)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '向HTTP输出流中写入取得的数据信息 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resp.Write(colHeaders)</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim row As DataRow<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '逐行处理数据&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For Each row In dt.Rows<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '在当前行中，逐列获得数据，数据之间以\t分割，结束时加回车符\n <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For i = 0 To dt.Columns.Count - 2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ls_item &amp;= row(i).ToString() &amp; Chr(9)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next i<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ls_item &amp;= row(i).ToString() &amp; Chr(13)</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '当前行数据写入HTTP输出流，并且置空ls_item以便下行数据&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resp.Write(ls_item)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ls_item = ""<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '写缓冲区中的数据到HTTP头文件中 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resp.End()<BR>&nbsp;&nbsp;&nbsp; End Sub<BR>&nbsp;&nbsp; 2.读取Excel文件<BR>&nbsp;&nbsp;&nbsp;&nbsp; ' &lt;summary&gt;<BR>&nbsp;&nbsp;&nbsp; '&nbsp; 读取Excel文件<BR>&nbsp;&nbsp;&nbsp; ' &lt;/summary&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;param name="dt"&gt;要转换为Excel文件的表&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;param name="page"&gt;页面Page对象,用法: 将me.Page传递过来即可&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;return&gt;数据集DataSet&lt;/return&gt;<BR>&nbsp;&nbsp;&nbsp; Public Function ReadExcelFileToDataSet(ByVal strFileName As String) As DataSet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Try</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '建立一个专门存放Excel文件的目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If Directory.Exists(Page.Server.MapPath("ExcelFolder")) = False Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Directory.CreateDirectory(Page.Server.MapPath("ExcelFolder"))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim strConn As String<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" &amp; "Data Source=" &amp; </P>
<P>Page.Server.MapPath(".") &amp; "\ExcelFolder\" &amp; strFileName &amp; ";" &amp; "Extended </P>
<P>Properties=Excel 8.0;"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim conn As OleDb.OleDbConnection = New OleDb.OleDbConnection(strConn)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim strExcel As String = "select * from [sheet1$]"<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim ds As DataSet = New DataSet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; conn.Open()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim adapter As OleDbDataAdapter = New OleDbDataAdapter(strExcel, strConn)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter.Fill(ds)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return ds<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Catch ex As Exception<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Throw ex<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End Try<BR>&nbsp;&nbsp;&nbsp; End Function</P>
<P>&nbsp;&nbsp; 生成是成功的，但读取不成功，提示:"数据源格式有误!" <BR>&nbsp;&nbsp; 一直是认为:ReadExcelFileToDataSet方法有误,调试了半天，找了N多资料也不能成功!<BR>&nbsp;&nbsp; 后来经过"时间的流逝",终久确认第二个方法没有错误，是完全正确的，是第一个方法<BR>&nbsp;&nbsp; 生成格式的问题. 于是我将第一个方法换为下面的方法,读取和写入就OK了.<BR>&nbsp; <BR>&nbsp;3.生成Excel文件方法二: <BR>&nbsp;&nbsp;&nbsp;&nbsp; ' &lt;summary&gt;<BR>&nbsp;&nbsp;&nbsp; '&nbsp; 下载Excel方法2(用office-Excel-Com组件对象实现)<BR>&nbsp;&nbsp;&nbsp; ' &lt;/summary&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;param name="dt"&gt;要转换为Excel文件的表&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; ' &lt;param name="page"&gt;页面Page对象,用法: 将me.Page传递过来即可&lt;/param&gt;<BR>&nbsp;&nbsp;&nbsp; Public Sub DownLoadExcelToClient2(ByVal dt As DataTable)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '生成Excel操作相关对象<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim xlApp As Excel.Application<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim xlBook As Excel.Workbook<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim xlSheet As Excel.Worksheet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlApp = CType(CreateObject("Excel.Application"), Excel.Application)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlBook = CType(xlApp.Workbooks.Add, Excel.Workbook)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlSheet = CType(xlBook.Worksheets(1), Excel.Worksheet)</P>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'xlSheet.Range("A1:B1").Merge(0) '合并单元格<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'xlSheet.Cells(1, 1) = "员工资料信息:"</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '赋标题(Excel文件中的标题)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim rowIndex As Integer = 2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim colIndex As Integer = 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim Col As DataColumn<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim Row As DataRow<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For Each Col In dt.Columns<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colIndex = colIndex + 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlApp.Cells(rowIndex, colIndex) = Col.ColumnName<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '将表dt的所有行写入xlApp对象(Excel文件中的内容)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For Each Row In dt.Rows<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rowIndex = rowIndex + 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colIndex = 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For Each Col In dt.Columns<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colIndex = colIndex + 1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlApp.Cells(rowIndex, colIndex) = Row(Col.ColumnName)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlSheet.Application.Visible = True&nbsp;&nbsp; '置为可见</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '建立一个专门存放Excel文件的目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If Directory.Exists(Page.Server.MapPath("ExcelFolder")) = False Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Directory.CreateDirectory(Page.Server.MapPath("ExcelFolder"))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '删除服务端临时文件: download.xls<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If File.Exists(Page.Server.MapPath(".") &amp; "\ExcelFolder\download.xls") = True Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File.Delete(Page.Server.MapPath(".") &amp; "\ExcelFolder\download.xls")<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '在服务端保存download.xls<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlSheet.SaveAs(Page.Server.MapPath(".") &amp; "\ExcelFolder\download.xls")</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '杀死Excel进程<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim myproc As System.Diagnostics.Process = New System.Diagnostics.Process<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim proc As Process<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim procs() As Process = Process.GetProcessesByName("excel")&nbsp;&nbsp; '得到所有打开的进程<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For Each proc In procs<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If Not proc.CloseMainWindow() Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proc.Kill()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Next<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Catch<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End Try</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '这里用到个goto语句,是因为: 线程是异步执行的,下面的代码要访问download.xls文件,但有</P>
<P>少数情况下上面的线程<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '未能及时释放download.xls文件的指针,那么下面代码执行语句时会抛出异常, 当发生异常时</P>
<P>需要等待资源释放后,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '再重新访问该文件, 保证下载文件能够正确下载<BR>again:&nbsp; Try<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '输出到客户端()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If File.Exists(Page.Server.MapPath(".") &amp; "\ExcelFolder\download.xls") Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Dim TargetFile As FileInfo = New FileInfo(Page.Server.MapPath(".") &amp; </P>
<P>"\ExcelFolder\download.xls")<BR>&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; Page.Response.Clear()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '向输出流添加HTTP头 [指定下载/保存 对话框的文件名]<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page.Response.AppendHeader("Content-Disposition", "attachment; filename=" </P>
<P>+ Page.Server.UrlEncode(TargetFile.Name))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '向输出流添加HTTP头 [指定文件的长度,这样下载文件就会显示正确的进度<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page.Response.AppendHeader("Content-Length", TargetFile.Length.ToString())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '表明输出的HTTP为流[stream],因此客户端只能下载.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page.Response.ContentType = "application/octet-stream"<BR>&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; Page.Response.WriteFile(TargetFile.FullName)<BR>&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; Page.Response.End()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Catch<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.Sleep(10)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GoTo again<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End Try<BR>&nbsp;&nbsp;&nbsp; End Sub<BR>这说明：<BR>&nbsp;&nbsp;&nbsp; a. 生成Excel文件后，用户经过修改，还要反向读取此Excel文件(比如:反向更新到数据库中)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 就只能用: 3 和 2方法结合使用.&nbsp; <BR>&nbsp;&nbsp;&nbsp; b. 如果只是单向输出Excel文件，用1和2方法都可以. 不过用2的话还要安装Office-Excel,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般还要设置一下Com组件访问权限,添加对Com组件的引用: 添加: 引用-&gt;com-&gt;Microsoft Excel 11.0 object Library</P>
<P>(三).不能读取的原因 以及 权限问题解决</P>
<P>&nbsp; a. 原因是:&nbsp; 方法 1 是用流的格式实现的,简单的说它不是真正的Excel格式，而 3 是调用的<BR>&nbsp;&nbsp;&nbsp;&nbsp; Excel Com组件，生成的是真正的Excel文档,所以能读取(1也可以读取，但也要用Stream类读取， </P>
<P>&nbsp;&nbsp;&nbsp; 如果数据有些复杂的话，会很麻烦).&nbsp; 用1和3方法生成的文件及文件图标一模一样，并且用Excel&nbsp; </P>
<P>&nbsp;&nbsp;&nbsp; 应用程序打开后显示效果也是一样的.&nbsp; 但当用记事本分别打开1和3生成的*.xls文件时，就明<BR>&nbsp;&nbsp;&nbsp;&nbsp; 显看到它们的不同了.(您可以下载一下本示例代码程序，分别生成两个文件，对比一下)</P>
<P>&nbsp; b.在使用Excel com组件时除了装Office-Excel以外，一般还要设置一下Com的访问权限，步骤如下:&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp; I.如果是Window2003 -&gt;控制面版 -&gt; 管理工具 -&gt; 组件服务 -&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开树级目录找到子目录DCOM配置 -&gt; Microsoft Excel 应用程序 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt; 右击选“属性” -&gt; 在弹出对话窗口中选“安全”选项卡-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt; 将启动和激活权限设为自定义-&gt;点击编辑按钮-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;在新窗口中将Everyone用户加入,选中复选框"启动权限",给予启动权限</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp; II.如果是WindowXP -&gt;控制面版 -&gt; 管理工具 -&gt; 组件服务(繁体为"元件服务") -&gt; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开树级目录找到子目录DCOM配置 -&gt; Microsoft Excel 应用程序 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt; 右击选“属性” -&gt; 在弹出对话窗口中选“安全”选项卡-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt; 将启动和激活权限设为自定义-&gt;点击编辑按钮-&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt;在新窗口中将Everyone用户加入,选中复选框"远程启动",给予远程启动权限<BR>(四).使用Excel模板<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然Com组件功能已经比较全面，可以对任意一个单元格设置和赋值.但是如果数据集DataSet比 </P>
<P>&nbsp;&nbsp; 较复杂的话，全部用Com提供的方法实现就很麻烦了. 尤其是文档头和尾最难处理.<BR>&nbsp;&nbsp;&nbsp; 这时可以这样处理:<BR>&nbsp;&nbsp;&nbsp; a.先用Excel应用程序建立一个Excel文件，设置好头/尾样式和以及所有单元格的布局和格式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (这里就是作用office 家簇的 excel进行表格布局，可以任意操作)&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; b.将此文件保存到工程的一个文夹下面即可.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用法: <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 只需将2中的:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlBook = CType(xlApp.Workbooks.Add, Excel.Workbook) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 改为:&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlBook = xlApp.Workbooks.Add(page.MapPath(".") + "ExcelTemplate.xls")'使用現有模板<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 即可。 这样xlBook实际上是基于自己创建的模板的.<BR>&nbsp;&nbsp;&nbsp; 这样操作，一般表头和标题列，表尾列一般不用设置，只显示DataSet中的主要数据(甚至也不用显 </P>
<P>&nbsp;&nbsp; 示DataSet列名)</P>
<P>&nbsp;&nbsp;&nbsp; 最近给客户做一些Excel报表,我们是这样做的，直接把客户给的Excel需求文件作为了模板.<BR>&nbsp;&nbsp;&nbsp; 非常简便，更爽的是这样做报表跟客户要求的完全相同。</P>
<P>(五).代码示例下载</P>
<P>&nbsp;&nbsp; <A href="http://www.cnblogs.com/Files/ChengKing/OPExcel.rar">http://www.cnblogs.com/Files/ChengKing/OPExcel.rar</A></P>
<P>&nbsp;此示例在配置环境:&nbsp;&nbsp; WinXP(繁体) VS.net 2002&nbsp;&nbsp;&nbsp;&nbsp;WinXP(简体) Vs.net 2003&nbsp;</P>
<P>&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;&nbsp;&nbsp; &nbsp;Win2003 VS.net 2003&nbsp; 测试能够正确运行!</P>
<P></P>
<P>相关文章:</P>
<P><A href="http://blog.joycode.com/ghj/archive/2005/01/12/42861.aspx">http://blog.joycode.com/ghj/archive/2005/01/12/42861.aspx</A><BR><A href="http://cnbie.net/print_146048m63657.html">http://cnbie.net/print_146048m63657.html</A><BR><A href="http://blog.csdn.net/net_lover/archive/2004/06/08/6963.aspx">http://blog.csdn.net/net_lover/archive/2004/06/08/6963.aspx</A><BR><A href="http://dotnet.aspx.cc/ShowDetail.aspx?id=4EB79F05-B9A4-4E8A-836F-864393F40405">http://dotnet.aspx.cc/ShowDetail.aspx?id=4EB79F05-B9A4-4E8A-836F-864393F40405</A><BR><A href="http://dotnet.aspx.cc/ShowDetail.aspx?id=6AFBF00B-459D-4642-AD14-8A4765FFAFCC">http://dotnet.aspx.cc/ShowDetail.aspx?id=6AFBF00B-459D-4642-AD14-8A4765FFAFCC</A><BR><A href="http://dotnet.aspx.cc/ShowDetail.aspx?id=8A4CBF47-B888-4832-3389-ED3A3A3C8AAB">http://dotnet.aspx.cc/ShowDetail.aspx?id=8A4CBF47-B888-4832-3389-ED3A3A3C8AAB</A><BR><A href="http://support.microsoft.com/kb/317881/EN-US/">http://support.microsoft.com/kb/317881/EN-US/</A><BR><A href="http://study.99net.net/study/program/vb/1049955696.html">http://study.99net.net/study/program/vb/1049955696.html</A></P>
<P><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </P></SPAN><img src ="http://www.blogjava.net/songfei/aggbug/22968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 13:51 <a href="http://www.blogjava.net/songfei/articles/22968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在vb.net中实现窗体上回车键代替TAB键</title><link>http://www.blogjava.net/songfei/articles/22967.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 08 Dec 2005 05:47:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22967.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22967.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22967.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22967.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22967.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>&nbsp;
<P>在vb.net中实现窗体上回车键代替TAB键，用如下方法：</P>
<P>首先设置窗体的 KeyPreview&nbsp; 属性为true</P>
<P>然后加入以下代码：</P>
<P>Private Sub FrmLogin_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '用回车代替Tab<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If e.KeyChar = Chr(13) Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.Handled = True<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SendKeys.Send("{TAB}")<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End If<BR>&nbsp;&nbsp;&nbsp; End Sub<BR></P></SPAN><BR><img src ="http://www.blogjava.net/songfei/aggbug/22967.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-08 13:47 <a href="http://www.blogjava.net/songfei/articles/22967.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VB代码word,excel</title><link>http://www.blogjava.net/songfei/articles/22731.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Tue, 06 Dec 2005 07:51:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22731.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22731.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22731.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22731.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22731.html</trackback:ping><description><![CDATA[<TABLE class=partsmb cellSpacing=0 border=0>
<TBODY>
<TR>
<TD></TD>
<TD><SPAN id=_ctl2_lblPermalink>
<TABLE class="fixedTable blogpost" cellSpacing=0 width="100%" border=0>
<TBODY>
<TR>
<TD class=bvh8></TD></TR>
<TR>
<TD vAlign=top><SPAN class=bold id=LastMDatecns!1pjT6ZZPXrUDK3Cz9fSidDqg!110><STRONG>8月3日</STRONG></SPAN></TD></TR>
<TR>
<TD height=4><STRONG></STRONG></TD></TR>
<TR>
<TD class=blackline><STRONG></STRONG></TD></TR>
<TR>
<TD height=4><STRONG></STRONG></TD></TR>
<TR>
<TD class=ellipse><SPAN class=bvTitle id=subjcns!1pjT6ZZPXrUDK3Cz9fSidDqg!110><STRONG>这些VBA代码会有用</STRONG></SPAN></TD></TR>
<TR>
<TD class=bvh8><STRONG></STRONG></TD></TR>
<TR>
<TD id=msgcns!1pjT6ZZPXrUDK3Cz9fSidDqg!110>
<DIV><SPAN>QQ:有没有办法得到一个excle表的行的总数和列的总数？？ <BR>AA: <BR>xlSheet.UsedRange.Rows.Count <BR>xlSheet.UsedRange.Cols.Count <BR><BR>QQ: <BR>如何打开一个word的模板！ <BR>最近做一个word的模板程序，打开word是Set NewDoc = MyWord.Documents.Add <BR>这是一个新的doc,名字叫文档1（后面会累加，自动的），但是现在我希望直接新建打开一个我写好的模板程序，名字还是叫文档1。请问应该怎么写！ <BR>AA: <BR>On Error Resume Next '忽略错误 <BR>Set Wrd = GetObject(, "Word.Application") '查找一个正在运行的Word拷贝 <BR>If Err.Number &lt;&gt; 0 Then '如果 Word 没有运行则 <BR>Set Wrd = CreateObject("Word.Application") '运行它 <BR>End If <BR>Err.Clear '清除发生错误的 Err 对象 <BR>On Error GoTo 0 '保留普通错误进程 <BR><BR>Dim dot As String <BR>Dim doc As String <BR>Wrd.Visible =true <BR>dot = "C:\temp.dot" <BR>doc = "c:\temp.doc" <BR>Documents.Open FileName:=dot, _ <BR>ConfirmConversions:=False, ReadOnly:=True, AddToRecentFiles:=False, _ <BR>PasswordDocument:="", PasswordTemplate:="", Revert:=False, _ <BR>WritePasswordDocument:="", WritePasswordTemplate:="", Format:= _ <BR>0 <BR>Wrd.ActiveDocument.Close <BR>Wrd.Documents.Add Template:=dot, NewTemplate:=False <BR><BR>'结果系列操作 <BR>ActiveDocument.SaveAs FileName:=doc, FileFormat:=wdFormatDocument, _ <BR>LockComments:=False, Password:="", AddToRecentFiles:=True, WritePassword _ <BR>:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _ <BR>SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _ <BR>False <BR>'打印出来 <BR>ActiveDocument.PrintOut FileName:=doc, Range:=wdPrintAllDocument, Item:= _ <BR>wdPrintDocumentContent, Copies:=1, Pages:="", PageType:=wdPrintAllPages, _ <BR>ManualDuplexPrint:=False, Collate:=True, Background:=True, PrintToFile:= _ <BR>False, PrintZoomColumn:=0, PrintZoomRow:=0, PrintZoomPaperWidth:=0, _ <BR>PrintZoomPaperHeight:=0 <BR>Wrd.ActiveDocument.Close <BR><BR>WORD中打字 <BR>Selection.TypeText Text:="您好，先生" <BR><BR>如何让Word的保存命令调用我自己编写的保存方法？ <BR>在doc文档被修改以后，在退出的时候当提示用户文档已经修改，问是否保存 <BR>和直接点击保存按钮的时候，能否让Word去调用我自己编写的SaveDoc方法， <BR>如何实现？ <BR>创建名为“FileSave”的宏，把你的代码写入在这个宏中。当点击“保存”按钮或退出程序要求“保存”时，都会直接执行你的“FileSave”宏，而不再执行Word的内置命令。 <BR><BR><BR>怎么样判断Word文档中有没有图片? <BR>Word里的图片包括两种（据我所知），楼上的漏掉了InlineShapes <BR>If ActiveDocument.Shapes.Count + ActiveDocument.InlineShapes.Count &gt; 0 Then <BR>MsgBox "esit" <BR>Else <BR>MsgBox "Document doesn't contain a shape" <BR>End If <BR><BR><BR>QQ：怎样在程序中把图片写入到ｗｏｒｄ中。 <BR>AA： <BR>功能是：在指定位置插入图片并设置图片的格式（包括设置为衬托于文字下　　　　方） <BR>Sub 设置图片格式() <BR>Selection.InlineShapes.AddPicture FileName:="D:\Mypicture\800x600.jpg", _ <BR>LinkToFile:=False, SaveWithDocument:=True <BR>Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend <BR>Selection.InlineShapes(1).ConvertToShape.Select <BR>Selection.ShapeRange.Fill.Visible = msoFalse <BR>Selection.ShapeRange.Fill.Transparency = 0# <BR>Selection.ShapeRange.Line.Weight = 0.75 <BR>Selection.ShapeRange.Line.DashStyle = msoLineSolid <BR>Selection.ShapeRange.Line.Style = msoLineSingle <BR>Selection.ShapeRange.Line.Transparency = 0# <BR>Selection.ShapeRange.Line.Visible = msoFalse <BR>Selection.ShapeRange.LockAspectRatio = msoTrue <BR>Selection.ShapeRange.Height = 361.4 <BR>Selection.ShapeRange.Width = 481.6 <BR>Selection.ShapeRange.PictureFormat.Brightness = 0.5 <BR>Selection.ShapeRange.PictureFormat.Contrast = 0.5 <BR>Selection.ShapeRange.PictureFormat.ColorType = msoPictureAutomatic <BR>Selection.ShapeRange.PictureFormat.CropLeft = 0# <BR>Selection.ShapeRange.PictureFormat.CropRight = 0# <BR>Selection.ShapeRange.PictureFormat.CropTop = 0# <BR>Selection.ShapeRange.PictureFormat.CropBottom = 0# <BR>Selection.ShapeRange.RelativeHorizontalPosition = _ <BR>wdRelativeHorizontalPositionColumn <BR>Selection.ShapeRange.RelativeVerticalPosition = _ <BR>wdRelativeVerticalPositionPage <BR>Selection.ShapeRange.Left = wdShapeCenter <BR>Selection.ShapeRange.Top = wdShapeCenter <BR>Selection.ShapeRange.LockAnchor = False <BR>Selection.ShapeRange.WrapFormat.AllowOverlap = True <BR>Selection.ShapeRange.WrapFormat.Side = wdWrapBoth <BR>Selection.ShapeRange.WrapFormat.DistanceTop = CentimetersToPoints(0) <BR>Selection.ShapeRange.WrapFormat.DistanceBottom = CentimetersToPoints(0) <BR>Selection.ShapeRange.WrapFormat.DistanceLeft = CentimetersToPoints(0.32) <BR>Selection.ShapeRange.WrapFormat.DistanceRight = CentimetersToPoints(0.32) <BR>Selection.ShapeRange.WrapFormat.Type = 3 <BR>‘实际上真正有用的是下面的语句设置图片为衬托于文字下方 <BR>Selection.ShapeRange.ZOrder msoSendBehindText <BR>End Sub <BR><BR>QQ：有没有方法，把一个word文件，按编号返回一段一段的段落文章。 <BR>比如 <BR>1 XXXX <BR>1.1 YYYY <BR>1.1.1 ZZZZ <BR>QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ <BR>1.1.2 SSSS <BR>PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP <BR><BR>能够返回 一个编号对应的一个标题和一段话。 <BR>谢谢 <BR>AA： <BR>加载Microsoft Word 9.0 Object Library <BR>Dim dcApp As Word.Application <BR>Dim dcWd As Word.Document <BR><BR>Private Sub Form_Load() <BR>Set dcApp = New Word.Application <BR>Set dcWd = dcApp.Documents.Open("c:\rpt.doc") <BR><BR>For i = 1 To dcWd.Paragraphs.Count <BR>Debug.Print dcWd.Paragraphs(i).Range.Text <BR>Next <BR><BR><BR>dcWd.Close <BR>Set dcWd = Nothing <BR>dcApp.Quit <BR>Set dcApp = Nothing <BR>End Sub <BR><BR>QQ：如何用vb实现在word的bookmark后插入字符 <BR>在word模版中指定了boolmark:a, <BR>Dim wrdapp As Word.Application <BR>Dim wrddoc As Word.Document <BR>Dim strFileName As String <BR>Dim i As Variant <BR>dim s as string <BR><BR>s="要插入的字符" <BR>Set wrdapp = CreateObject("Word.Application") <BR>strFileName = App.Path &amp; "\temp.dot" <BR>Set wrddoc = wrdapp.Documents.Open(strFileName) <BR>i = wrddoc.Range.GoTo(wdGoToBookmark, , , "a") <BR>后面该如何写，才能将s插入到bookmark后面？另外我上面的代码正确吗？谢谢 <BR>？？？？？？？？？？？？？？ <BR><BR><BR>QQ： VBA:在word文档中搜索单词“审稿人”，将光标移到它后面，插入图片？怎么实现！！！ <BR>我现在可以打开文件和插入图片了，就是没有搜索单词、移动光标、插入指定大小的图片的功能，那位老大出来指点指点呀？ <BR><BR>我的代码如下： <BR>Option Explicit <BR>Dim Doc As New Document <BR>Dim Visi As Boolean <BR>Dim wordApp As Word.Application <BR>Dim docWord As Word.Document <BR>Private Sub Command2_Click() <BR>Set wordApp = New Word.Application <BR>Set docWord = Word.Documents.Open("D:\test.doc") <BR>ActiveDocument.Shapes.AddPicture ("d:\shan.jpg") <BR>docWord.Save <BR>docWord.Close <BR>wordApp.Application.Quit（） <BR>End Sub <BR>AA： <BR>wordApp.Find.ClearFormatting <BR><BR>wordApp.Find.Text = "审稿人" <BR>wordApp.Find.Replacement.Text = "" <BR>wordApp.Find.Forward = True <BR>wordApp.Find.Wrap = wdFindContinue <BR>wordApp.Find.Format = False <BR>wordApp.Find.MatchCase = False <BR>wordApp.Find.MatchWholeWord = False <BR>wordApp.Find.MatchByte = True <BR>wordApp.Find.CorrectHangulEndings = False <BR>wordApp.Find.MatchAllWordForms = False <BR>wordApp.Find.MatchSoundsLike = False <BR>wordApp.Find.MatchWildcards = False <BR>wordApp.Find.MatchFuzzy = False <BR><BR>wordApp.Find.Execute <BR><BR><BR>QQ:请问如何将加载的菜单不是以悬浮的菜单形式出现？ <BR>AA:CommandBar的Position属 <BR><BR>QQ: 在vb 中将word文件保存为纯文本 <BR>AA: <BR>Private Sub Command1_Click() <BR>Dim oW As Object, oD As Object, x As Object <BR>Set oW = CreateObject("word.application") <BR>Set oD = oW.documents.open("c:\aaa.doc") <BR>'oW.Visible = True <BR>For Each x In oD.words <BR>Text1 = Text1 &amp; x <BR>Next x <BR>Open "c:\bbb.txt" For Output As #1 <BR>Print #1, Text1 <BR>Close #1 <BR>oW.quit <BR>End Sub <BR><BR><BR>QQ:怎么在一个word文档的最后插入东西 <BR>AA: <BR>WORD XP的VB帮助中有示例： <BR>本示例在名为“Changes.doc”的文档末尾插入文本。“For Each...Next”语句用来判断此文档是否已打开。 <BR><BR>For Each aDocument In Documents <BR>If InStr(LCase$(aDocument.Name), "changes.doc") Then <BR>Set myRange = Documents("Changes.doc").Content <BR>myRange.InsertAfter "the end." <BR>End If <BR>Next aDocument <BR><BR>QQ:在WORD的宏里如何编写查询页数和行数， <BR>AA: <BR>ActiveDocument.BuiltInDocumentProperties(wdPropertyPages) <BR>ActiveDocument.BuiltInDocumentProperties(wdPropertyLines) <BR><BR><BR>QQ:请问网页考到word后，那个向下的箭头是什么标记，如何自动替换掉？手工替换很麻烦阿！但又不知道这是什么标记，无法下手阿。急用！！ <BR>AA: <BR>手工换行符 <BR><BR>可以用查找替换的，或者试试这个 <BR><BR>Sub blankdel() <BR>Dim i As Integer <BR>For i = ActiveDocument.Paragraphs.Count To 1 Step -1 <BR>ActiveDocument.Paragraphs(i).Range.Select <BR>a = Selection.Words.Count <BR>If a = 1 Then <BR>Selection.Delete <BR>m = m + 1 <BR>End If <BR>Next i <BR>MsgBox "共删除空白段落" &amp; m &amp; "个" <BR>End Sub <BR><BR><BR>按ALT+F11,把代码COPY进去运行一下就行了 <BR><BR><BR>QQ:请问怎么样用word对象中控制word的分页？ <BR>AA: <BR>我刚刚试出来的：此VB6下的代码可以解你问题 <BR><BR>Set pword = CreateObject("Word.Application") <BR>pword.Documents.Add dotName, False <BR>pword.WindowState = 2 'wdWindowStateMinimize '2 <BR><BR>pword.Selection.InsertBreak wdPageBreak <BR><BR><BR>QQ:我想控制用户只能修改Word文件的部分内容，所以需要设置部分区域为只读，不知道该用什么方法，请大家赐教。 <BR>AA: <BR>Selection.InsertBreak Type:=wdSectionBreakContinuous <BR>ActiveDocument.Sections(1).ProtectedForForms = False <BR>ActiveDocument.Sections(2).ProtectedForForms = True <BR>ActiveDocument.Protect Password:="", NoReset:=False, Type:= _ <BR>wdAllowOnlyFormFields <BR><BR><BR>QQ:请问怎么插入图片的 <BR>AA: <BR>Dim myShape As Shape <BR>Dim MyInshape As InlineShape <BR>'插入一个嵌入式图片对象 <BR>Set MyInshape = Selection.InlineShapes.AddPicture(FileName:="D:\pic001.jpg", _ <BR>LinkToFile:=False, SaveWithDocument:=True) <BR>'将InlineShape对象转变为Shape对象 <BR>Set myShape = MyInshape.ConvertToShape <BR>'使图片浮于文字上方 <BR>myShape.WrapFormat.Type = wdWrapNone <BR><BR><BR>QQ:如何访问表格单元格内容 <BR>AA： <BR>objWordDoc.Tables(3).Cell(1, 1).Range.Text <BR></SPAN></DIV></TD></TR></TBODY></TABLE></SPAN></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/songfei/aggbug/22731.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-06 15:51 <a href="http://www.blogjava.net/songfei/articles/22731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP导出Excel数据的四种方法 </title><link>http://www.blogjava.net/songfei/articles/22712.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Tue, 06 Dec 2005 06:43:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22712.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22712.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22712.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22712.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22712.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="95%" border=0>
<TBODY>
<TR>
<TD align=middle width="100%"><FONT size=3><B>ASP导出Excel数据的四种方法 </B></FONT></TD></TR>
<TR>
<TD class=text9pt align=middle width="100%">
<HR width="50%" noShade SIZE=1>
<FONT size=+0>摘自：西部asp联盟&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 人气：17370</FONT> </TD></TR>
<TR>
<TD width="100%" height=10></TD></TR>
<TR>
<TD width="100%">
<TABLE width="90%" align=center border=0>
<TBODY>
<TR>
<TD class=text9pt>
<TABLE width="50%" align=right border=0>
<TBODY>
<TR>
<TD width="100%" height=10>
<SCRIPT language=javascript src="http://usms.tom.com/wlqy.js?tomuserid=9247"></SCRIPT>
</TD></TR></TBODY></TABLE>
<P>一、使用OWC <BR>　　什么是OWC？ <BR>　　OWC是Office Web Compent的缩写，即Microsoft的Office Web组件，它为在Web中绘制图形提供了灵活的同时也是最基本的机制。在一个intranet环境中，如果可以假设客户机上存在特定的浏览器和一些功能强大的软件（如IE5和Office 2000），那么就有能力利用Office Web组件提供一个交互式图形开发环境。这种模式下，客户端工作站将在整个任务中分担很大的比重。 <BR>&lt;%<BR>Option Explicit <BR>Class ExcelGen <BR>Private objSpreadsheet <BR>Private iColOffset <BR>Private iRowOffset </P><BR>
<P>Sub Class_Initialize() <BR>Set objSpreadsheet = Server.CreateObject("OWC.Spreadsheet") <BR>iRowOffset = 2 <BR>iColOffset = 2 <BR>End Sub </P><BR>
<P>Sub Class_Terminate() <BR>Set objSpreadsheet = Nothing "Clean up <BR>End Sub </P><BR>
<P>Public Property Let ColumnOffset(iColOff) <BR>If iColOff ＞ 0 then <BR>iColOffset = iColOff <BR>Else <BR>iColOffset = 2 <BR>End If <BR>End Property </P><BR>
<P>Public Property Let RowOffset(iRowOff) <BR>If iRowOff ＞ 0 then <BR>iRowOffset = iRowOff <BR>Else <BR>iRowOffset = 2 <BR>End If <BR>End Property Sub GenerateWorksheet(objRS) <BR>"Populates the Excel worksheet based on a Recordset"s contents <BR>"Start by displaying the titles <BR>If objRS.EOF then Exit Sub <BR>Dim objField, iCol, iRow <BR>iCol = iColOffset <BR>iRow = iRowOffset <BR>For Each objField in objRS.Fields <BR>objSpreadsheet.Cells(iRow, iCol).Value = objField.Name <BR>objSpreadsheet.Columns(iCol).AutoFitColumns <BR>"设置Excel表里的字体 <BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = True <BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 10 <BR>objSpreadsheet.Cells(iRow, iCol).Halignment = 2 "居中 <BR>iCol = iCol + 1 <BR>Next "objField <BR>"Display all of the data <BR>Do While Not objRS.EOF <BR>iRow = iRow + 1 <BR>iCol = iColOffset <BR>For Each objField in objRS.Fields <BR>If IsNull(objField.Value) then <BR>objSpreadsheet.Cells(iRow, iCol).Value = "" <BR>Else <BR>objSpreadsheet.Cells(iRow, iCol).Value = objField.Value <BR>objSpreadsheet.Columns(iCol).AutoFitColumns <BR>objSpreadsheet.Cells(iRow, iCol).Font.Bold = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Italic = False <BR>objSpreadsheet.Cells(iRow, iCol).Font.Size = 10 <BR>End If <BR>iCol = iCol + 1 <BR>Next "objField <BR>objRS.MoveNext <BR>Loop <BR>End Sub Function SaveWorksheet(strFileName) </P><BR>
<P>"Save the worksheet to a specified filename <BR>On Error Resume Next <BR>Call objSpreadsheet.ActiveSheet.Export(strFileName, 0) <BR>SaveWorksheet = (Err.Number = 0) <BR>End Function <BR>End Class </P><BR>
<P>Dim objRS <BR>Set objRS = Server.CreateObject("ADODB.Recordset") <BR>objRS.Open "SELECT * FROM xxxx", "Provider=SQLOLEDB.1;Persist Security </P><BR>
<P>Info=True;User ID=xxxx;Password=xxxx;Initial Catalog=xxxx;Data source=xxxx;" <BR>Dim SaveName <BR>SaveName = Request.Cookies("savename")("name") <BR>Dim objExcel <BR>Dim ExcelPath <BR>ExcelPath = "Excel\" &amp; SaveName &amp; ".xls" <BR>Set objExcel = New ExcelGen <BR>objExcel.RowOffset = 1 <BR>objExcel.ColumnOffset = 1 <BR>objExcel.GenerateWorksheet(objRS) <BR>If objExcel.SaveWorksheet(Server.MapPath(ExcelPath)) then <BR>"Response.Write "＜html＞＜body bgcolor="gainsboro" text="#000000"＞已保存为Excel文件. </P><BR>
<P>＜a href="" &amp; server.URLEncode(ExcelPath) &amp; ""＞下载＜/a＞" <BR>Else <BR>Response.Write "在保存过程中有错误!" <BR>End If <BR>Set objExcel = Nothing <BR>objRS.Close <BR>Set objRS = Nothing <BR>%＞&nbsp; </P><BR>
<P>二、用Excel的Application组件在客户端导出到Excel或Word <BR>　　<BR>注意：两个函数中的“data“是网页中要导出的table的 id </P><BR>
<P>＜input type="hidden" name="out_word" onclick="vbscript:buildDoc" value="导出到word" class="notPrint"＞ <BR>＜input type="hidden" name="out_excel" onclick="AutomateExcel();" value="导出到excel" class="notPrint"＞&nbsp; </P><BR>
<P>导出到Excel代码 <BR>＜SCRIPT LANGUAGE="javascript"＞ <BR>＜!-- <BR>function AutomateExcel() <BR>{ <BR>// Start Excel and get Application object. <BR>var oXL = new ActiveXObject("Excel.Application"); <BR>// Get a new workbook. <BR>var oWB = oXL.Workbooks.Add(); <BR>var oSheet = oWB.ActiveSheet; <BR>var table = document.all.data; <BR>var hang = table.rows.length; <BR>var lie = table.rows(0).cells.length; </P><BR>
<P>// Add table headers going cell by cell. <BR>for (i=0;i＜hang;i++) <BR>{ <BR>for (j=0;j＜lie;j++) <BR>{ <BR>oSheet.Cells(i+1,j+1).value = table.rows(i).cells(j).innerText; <BR>} <BR>} <BR>oXL.Visible = true; <BR>oXL.UserControl = true; <BR>} <BR>//--＞ <BR>＜/SCRIPT＞&nbsp; </P><BR>
<P>导出到Word代码 <BR>＜script language="vbscript"＞ <BR>Sub buildDoc <BR>set table = document.all.data <BR>row = table.rows.length <BR>column = table.rows(1).cells.length <BR>Set objWordDoc = CreateObject("Word.Document") <BR>objWordDoc.Application.Documents.Add theTemplate, False <BR>objWordDoc.Application.Visible=True <BR>Dim theArray(20,10000) <BR>for i=0 to row-1 <BR>for j=0 to column-1 <BR>theArray(j+1,i+1) = table.rows(i).cells(j).innerTEXT <BR>next <BR>next <BR>objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("综合查询结果集") //显示表格标题 </P><BR>
<P>objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("") <BR>Set rngPara = objWordDoc.Application.ActiveDocument.Paragraphs(1).Range <BR>With rngPara <BR>.Bold = True //将标题设为粗体 <BR>.ParagraphFormat.Alignment = 1 //将标题居中 <BR>.Font.Name = "隶书" //设定标题字体 <BR>.Font.Size = 18 //设定标题字体大小 <BR>End With <BR>Set rngCurrent = objWordDoc.Application.ActiveDocument.Paragraphs(3).Range <BR>Set tabCurrent = ObjWordDoc.Application.ActiveDocument.Tables.Add(rngCurrent,row,column) </P><BR>
<P>for i = 1 to column </P><BR>
<P>objWordDoc.Application.ActiveDocument.Tables(1).Rows(1).Cells(i).Range.InsertAfter theArray(i,1) <BR>objWordDoc.Application.ActiveDocument.Tables(1).Rows(1).Cells(i).Range.ParagraphFormat.alignment=1 <BR>next <BR>For i =1 to column <BR>For j = 2 to row <BR>objWordDoc.Application.ActiveDocument.Tables(1).Rows(j).Cells(i).Range.InsertAfter theArray(i,j) <BR>objWordDoc.Application.ActiveDocument.Tables(1).Rows(j).Cells(i).Range.ParagraphFormat.alignment=1 <BR>Next <BR>Next <BR>End Sub <BR>＜/SCRIPT＞&nbsp; </P><BR>
<P>三、直接在IE中打开，再存为EXCEL文件 </P><BR>
<P>　　把读出的数据用＜table＞格式，在网页中显示出来，同时，加上下一句即可把EXCEL表在客客户端显示。 <BR>＜%response.ContentType ="application/vnd.ms-excel"%＞&nbsp; <BR>　　注意：显示的页面中，只把＜table＞输出，最好不要输出其他表格以外的信息。 </P><BR>
<P>四、导出以半角逗号隔开的csv <BR>　　用fso方法生成文本文件的方法，生成一个扩展名为csv文件。此文件，一行即为数据表的一行。生成数据表字段用半角逗号隔开。（有关fso生成文本文件的方法，在此就不做介绍了） <BR>　　CSV文件介绍 （逗号分隔文件） <BR>　　选择该项系统将创建一个可供下载的CSV 文件； CSV是最通用的一种文件格式，它可以非常容易地被导入各种PC表格及数据库中。<BR>　　请注意即使选择表格作为输出格式，仍然可以将结果下载CSV文件。在表格输出屏幕的底部，显示有 "CSV 文件"选项，点击它即可下载该文件。<BR>　　如果您把浏览器配置为将您的电子表格软件与文本（TXT）/逗号分隔文件（CSV） 相关联，当您下载该文件时，该文件将自动打开。下载下来后，如果本地已安装EXCEL，点击此文件，即可自动用EXCEL软件打开此文件。</P></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/songfei/aggbug/22712.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-06 14:43 <a href="http://www.blogjava.net/songfei/articles/22712.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Word模板</title><link>http://www.blogjava.net/songfei/articles/22685.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Tue, 06 Dec 2005 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/22685.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/22685.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/22685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/22685.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/22685.html</trackback:ping><description><![CDATA[<DIV align=center>
<TABLE cellSpacing=0 cellPadding=0 width="90%" border=0>
<TBODY>
<TR>
<TD style="WIDTH: 520px; WORD-BREAK: break-all" width="100%">曾有编程爱好者多次求我帮做Word模板，填写资料。当时也找不到资料。只告诉他<BR>要写资料的那一页用EXCEL，因EXCEL的参考资料多。后见他在多个论坛求助，未见解决。<BR>刚好闲点，花点时间研究了一下WORD，终于知道怎样如控制EXCEL一样来控制WORD。<BR>写成例子贴出来与大家共享,都有两方法，一是直接用代码编程创建文档，另是在WORD或<BR>EXCEL中作好模板，用模板创建，添写资料。我中意后者。<BR>&nbsp;&nbsp;另附 GRID 模仿DELPHI的显示<BR><BR>总结以下几点，就可更加发挥：<BR><BR>一、要实现的目的，先在WORD或EXCEL中录制宏。然后根据宏来修改做成VFP的代码。<BR><BR>二、对象的属性不同。<BR>&nbsp;&nbsp;&nbsp;&nbsp;a、WORD ,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、 凡有selection的为应用程序属性<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord=CREATEOBJECT('word.application')&nbsp;&nbsp;&amp;&amp;创建word目标<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.Selection<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**** Word多数用它**********<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.quit &amp;&amp;退出word<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、OleWord.Documents<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.Documents.add() &amp;&amp;增加新的word文档，有路径文件名是以它作模板打开<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.Documents.open("D:\test.doc") &amp;&amp;打开指定的文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.Documents.close(.F.) &amp;&amp;关闭所有打开的文档不保存，不要.F.，调出对话框<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、页面设置OleWord.ActiveDocument.PageSetup<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4、OleWord.ActiveDocument<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.ActiveDocument.Save &amp;&amp;保存<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.ActiveDocument.SaveAs("D:\test.doc")　&amp;&amp;最简单的另存<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OleWord.ActiveDocument.close &amp;&amp;关闭当前word文档<BR><BR>&nbsp;&nbsp;&nbsp;b、EXCEL<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、凡有selection的为应用程序属性 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp=CREATEOBJECT('Excel.application')<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.Selection<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.quit&nbsp;&nbsp;&amp;&amp;退出Excel<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2、XLApp.WorkBooks<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.WorkBooks.Add( ) &amp;&amp;增加新的EXCEL，加有路径文件名是以它作模板打开<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.Workbooks.Open("D:\test.xls")&nbsp;&nbsp;&amp;&amp; 打开指定工作簿<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.Workbooks.close(.F.)&nbsp;&nbsp;&amp;&amp;关闭所有打开的工作簿不保存，不要.F.，调出对话框<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3、页面设置 XLApp.ActiveSheet.PageSetup<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4、XLApp.ActiveSheet<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;********Excel多数用它与Word不同**********<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5、XLApp.ActiveWorkbook<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.ActiveWorkbook.Save&nbsp;&nbsp;&amp;&amp;保存　<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.ActiveWorkbook.SaveAs("D:\ABC\22.xls") &amp;&amp;另存为<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.ActiveWorkbook.close&nbsp;&nbsp;&nbsp;&amp;&amp;关闭当前工作簿<BR>三、WORD/EXCEL宏与VFP表示方法不同&nbsp;&nbsp;&nbsp;<BR><BR>&nbsp;&nbsp;a、WORD打开<BR>&nbsp;&nbsp;&nbsp;OleWord.Documents.open("D:\test.doc",.F.,.F.,.F.,'456','123',.F.,'','',.F.) &amp;&amp;根据宏函数改，与保存不同方式,456为打开密码，123为只读密码<BR><BR>*宏函数 Documents.Open FileName:="temp.doc", ConfirmConversions:=False, ReadOnly:= _<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;False, AddToRecentFiles:=False, PasswordDocument:="456", PasswordTemplate _<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:="123", Revert:=False, WritePasswordDocument:="123", WritePasswordTemplate _<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:="", Format:=wdOpenFormatAuto<BR>&nbsp;&nbsp;b、EXCEL只读保护<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.ActiveSheet.protect('123') &amp;&amp;用123密码锁起只读　<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XLApp.ActiveSheet.unprotect('123')&nbsp;&nbsp;&amp;&amp;用123密码解锁&nbsp;&nbsp;&nbsp;<BR><BR>*宏函数(用123密码只读锁)&nbsp;&nbsp;ActiveSheet.Protect DrawingObjects:=True, Contents:=True, Scenarios:=True<BR>* 用123密码解锁&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActiveSheet.Unprotect&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR><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;&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;&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;xj@meyerdyeing.com<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;&nbsp;&nbsp;&nbsp;&nbsp;2005/11/06&nbsp;&nbsp;&nbsp;&nbsp;<BR><BR>示例:<BR><A href="http://upload.programfan.com/upfile/20051122194626.rar" target=_blank>http://upload.programfan.com/upfile/20051122194626.rar </A><BR><BR></TD></TR></TBODY></TABLE></DIV>
<P></P>
<DIV align=center>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=0 width=755 bgColor=#f9ffff borderColorLight=#c0c0c0 border=1>
<TBODY>
<TR>
<TD vAlign=top width=164></TD>
<TD vAlign=top width=590>
<DIV align=center>
<TABLE cellSpacing=0 cellPadding=0 width=531 border=0>
<TBODY>
<TR>
<TD width=527>发表时间：2005-11-5 14:34:00&nbsp;&nbsp;&nbsp; </TD></TR></TBODY></TABLE></DIV>
<HR SIZE=1>

<P align=right>　<B>第<FONT color=#ff0000> 1 </FONT>楼&nbsp;&nbsp;</B> 
<DIV align=center>
<TABLE cellSpacing=0 cellPadding=0 width="90%" border=0>
<TBODY>
<TR>
<TD style="WIDTH: 520px; WORD-BREAK: break-all" width="100%">部分代码：<BR>*用WORD创建新文档，再根据DBF的资料创建自几所需要的表格文档<BR><BR>Thisform.chnagedbf&nbsp;&nbsp;&amp;&amp;转表查询生成新表、公用变量k,arrcolor[j,k],arrWash[1],arrCrock[1] <BR>&nbsp;&nbsp;&nbsp;WAIT windows("起动WORD制做文档，请稍等....") NOWAIT AT MROW(Thisform.Name,3),MCOL(Thisform.Name,3)<BR>OleWord=CREATEOBJECT('word.application')&nbsp;&nbsp;&amp;&amp;创建word目标<BR>OleWord.Visible=.F.&nbsp;&nbsp;&amp;&amp;word隐藏，为.F.可在后台操作<BR>OleWord.Documents.add() &amp;&amp;增加新的word文档<BR>*-- 页面设置<BR>WITH OleWord.ActiveDocument.PageSetup<BR>*1．设置顶边距为2厘米<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TopMargin=2/0.035<BR>*2．设置底边距为4厘米<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.BottomMargin=4/0.035<BR>*3．设置左边距为2厘米<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.LeftMargin=2/0.035<BR>*4．设置右边距为2厘米<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.RightMargin=2/0.035<BR>*页面0为纵向，1为横向&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Orientation=1<BR>&nbsp;&nbsp;&nbsp;ENDWITH <BR>**********************************************************************************<BR>WITH OleWord.Selection<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph&nbsp;&nbsp;&amp;&amp;回车符<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Text="致"&nbsp;&nbsp;&amp;&amp;加完是选定状态 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Font.size=20&nbsp;&nbsp;&nbsp;&amp;&amp;字体大小<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1) &amp;&amp;加完是选定状态，移动一次才不覆盖,3是右移参数，左移1字节。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(SPACE(4)+"兴启")&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Font.size=20&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(SPACE(6)+"多谢贵公司的支持，贵公司在我厂所配COT样办牢度如下：")&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Font.size=14&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph<BR>ENDWITH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>******创建表格*******************************<BR>&nbsp;&nbsp;OleWord.Selection.TypeParagraph<BR>&nbsp;&nbsp;OleWord.Selection.TypeParagraph<BR>&nbsp;&nbsp;OleWord.Selection.Moveup(5,1)&nbsp;&nbsp;&nbsp;&nbsp;&amp;&amp;第一个5是上移参数，第二个数字是上移1行,留一空行在格表下面<BR>&nbsp;&nbsp;otemp=OleWord.Selection.Range<BR>&nbsp;&nbsp;OleWord.ActiveDocument.Tables.Add(otemp,k+3,6,5,0) &amp;&amp;插入k+3行6列表格<BR>&nbsp;&nbsp;OleWord.Selection.SelectRow <BR>&nbsp;&nbsp;&amp;&amp;光标在第一格，要移动用Moveright() 等<BR><BR>WITH OleWord.Selection <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).Rows.Height=0.77/0.035&nbsp;&nbsp;&amp;&amp;选定表格所有行高0.77CM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).Columns.PreferredWidth=2.5/0.035 &amp;&amp;选定表格所有列宽 1.9cm <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).Columns(1).PreferredWidth=4.73/0.035 &amp;&amp;选定表格第一列宽 4.73cm<BR>&nbsp;&nbsp;&nbsp;&nbsp;*添加数据,表格合并后就不能用此方法加资料<BR>&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).rows(3).cells(3).range.insertafter("颜色变化") <BR>&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).rows(3).cells(4).range.insertafter("颜色沾色")&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).rows(3).cells(5).range.insertafter("干 擦") <BR>&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).rows(3).cells(6).range.insertafter("湿 擦")&nbsp;&nbsp;<BR>&nbsp;&nbsp;FOR i=1 TO k&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;FOR j=1 TO 6<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Tables(1).rows(i+3).cells(j).range.insertafter(arrcolor[i,j])&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;ENDFOR <BR>&nbsp;&nbsp;ENDFOR <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**选定合并&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveLeft(3,1)&nbsp;&nbsp;&amp;&amp;左移去掉选定.第一个3是左移参数，第二个数字是左移1字节<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveDown(5,2,1) &amp;&amp;下移两格，5是下移参数，2是移两格，1是按SHIFT,选择3格&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Cells.Merge&nbsp;&nbsp;&amp;&amp;合并选定的三格<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveRight(3,1) &amp;&amp;右移去掉选定.第一个3是右移参数，第二个数字是右移1格<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveDown(5,2,1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Cells.Merge&nbsp;&nbsp;&amp;&amp;合并选定的三格<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveRight(3,1) &amp;&amp;右移一格去掉选定 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,2,1)&nbsp;&nbsp;&nbsp;&amp;&amp;3是右移参数，右移1格,最后1是按SHIFT键，变成选定二格。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Cells.Merge&nbsp;&nbsp;&amp;&amp;合并选定的两格<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveDown(5,1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,2,1)&nbsp;&nbsp;&nbsp;&amp;&amp;3是右移参数，左移1格,最后1是按SHIFT键，变成选定二格。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Cells.Merge&nbsp;&nbsp;&amp;&amp;合并选定的两格<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1) &amp;&amp;右移一格去掉选定 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,2,1)&nbsp;&nbsp;&nbsp;&amp;&amp;3是右移参数，左移1格,最后1是按SHIFT键，变成选定二格。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Cells.Merge&nbsp;&nbsp;&amp;&amp;合并选定的两格&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveup(5,1) &amp;&amp;上移一格，5是下移参数，2是移两格，1是按SHIFT,选择3格&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,2,1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Cells.Merge <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;***加入资料,因要合并不方便操作，所以合并后加放标题资料 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter("摩&nbsp;&nbsp;擦") <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveDown(5,1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(arrCrock[1])&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveLeft(3,2) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(arrWash[1]) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveup(5,1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter("耐&nbsp;&nbsp;洗") <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveLeft(3,2) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter("颜 色") <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveLeft(3,2) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter("色 号") <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveDown(5,k,1) &amp;&amp;5是下移参数，下移k+2格,最后1是按SHIFT键，变成选定多格。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveRight(3,5,1)&nbsp;&nbsp;&amp;&amp;3是右移参数，右移5格,最后1是按SHIFT键，变成选定多格。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ParagraphFormat.Alignment=1&nbsp;&nbsp;&amp;&amp; 1居中　2左对齐，3右对齐，4分散对齐 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveDown(5,1) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(SPACE(4)+"祝")&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveRight(3,1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter("生意兴隆！")&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.MoveRight(3,1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(SPACE(25)+"先科有限公司")&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Font.size=20&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1)&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TypeParagraph&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.insertafter(SPACE(30)+DTOC(DATE())) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Moveright(3,1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>ENDWITH <BR>&nbsp;&nbsp;MESSAGEBOX("制作文档完毕!",64,"提示")<BR><BR>&nbsp;&nbsp;&nbsp;OleWord.Visible=.T.</TD></TR></TBODY></TABLE></DIV></TD></TR></TBODY></TABLE></DIV><img src ="http://www.blogjava.net/songfei/aggbug/22685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-12-06 11:23 <a href="http://www.blogjava.net/songfei/articles/22685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现的18位身份证格式验证算法</title><link>http://www.blogjava.net/songfei/articles/20278.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 17 Nov 2005 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/20278.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/20278.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/20278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/20278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/20278.html</trackback:ping><description><![CDATA[<DIV align=center>
<H1 class=aTitle><FONT size=5>C#实现的18位身份证格式验证算法</FONT></H1></DIV>
<TABLE width="97%" align=center>
<TBODY>
<TR>
<TD width=120><FONT size=5>[日期：<SPAN id=TimeLabel>2004-11-07</SPAN>]</FONT></TD>
<TD align=middle><FONT size=5>来源：<SPAN id=SourceLabel>CSDN</SPAN>&nbsp; 作者：<SPAN id=AuthorLabel></SPAN></FONT></TD>
<TD align=right width=100><FONT size=5>[字体：</FONT><A href="javascript:ContentSize(16)"><FONT size=5>大</FONT></A><FONT size=5> </FONT><A href="javascript:ContentSize(14)"><FONT size=5>中</FONT></A><FONT size=5> </FONT><A href="javascript:ContentSize(12)"><FONT size=5>小</FONT></A><FONT size=5>] </FONT></TD></TR></TBODY></TABLE>
<DIV class=content id=BodyLabel style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><SPAN id=ArticleContent1_ArticleContent1_lblContent><FONT size=5>&nbsp; 18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份号码》中做了明确的规定。 GB11643-1999《公民身份号码》为GB11643-1989《社会保障号码》的修订版，其中指出将原标准名称"社会保障号码"更名为"公民身份号码"，另外GB11643-1999《公民身份号码》从实施之日起代替GB11643-1989。GB11643-1999《公民身份号码》主要内容如下：<BR>一、范围<BR>&nbsp;&nbsp;&nbsp;&nbsp; 该标准规定了公民身份号码的编码对象、号码的结构和表现形式，使每个编码对象获得一个唯一的、不变的法定号码。<BR>二、编码对象<BR>&nbsp;&nbsp;&nbsp;&nbsp; 公民身份号码的编码对象是具有中华人民共和国国籍的公民。<BR>三、号码的结构和表示形式<BR>1、号码的结构<BR>&nbsp;&nbsp;&nbsp; 公民身份号码是特征组合码，由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。<BR>2、地址码<BR>&nbsp;&nbsp;&nbsp; 表示编码对象常住户口所在县(市、旗、区)的行政区划代码，按GB/T2260的规定执行。<BR>3、出生日期码<BR>&nbsp;&nbsp;&nbsp; 表示编码对象出生的年、月、日，按GB/T7408的规定执行，年、月、日代码之间不用分隔符。<BR>4、顺序码<BR>&nbsp;&nbsp;&nbsp;&nbsp; 表示在同一地址码所标识的区域范围内，对同年、同月、同日出生的人编定的顺序号，顺序码的奇数分配给男性，偶数分配给女性。<BR>5、校验码<BR>（1）十七位数字本体码加权求和公式<BR>S = Sum(Ai * Wi), i = 0, ... , 16 ，先对前17位数字的权求和<BR>Ai:表示第i位置上的身份证号码数字值<BR>Wi:表示第i位置上的加权因子<BR>Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 </FONT>
<P><FONT size=5>（2）计算模<BR>Y = mod(S, 11)</FONT></P>
<P><FONT size=5>（3）通过模得到对应的校验码<BR>Y: 0 1 2 3 4 5 6 7 8 9 10<BR>校验码: 1 0 X 9 8 7 6 5 4 3 2<BR>四、举例如下：<BR>北京市朝阳区: 11010519491231002X<BR>广东省汕头市: 440524188001010014</FONT></P>
<P><BR><BR><FONT size=5><FONT color=#ffa500>以下是程序代码：</FONT><BR>private string CheckCidInfo(string cid)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;string[] aCity = new string[]{null,null,null,null,null,null,null,null,null,null,null,"北京","天津","河北","山西","内蒙古",null,null,null,null,null,"辽宁","吉林","黑龙江",null,null,null,null,null,null,null,"上海","江苏","浙江","安微","福建","江西","山东",null,null,null,"河南","湖北","湖南","广东","广西","海南",null,null,null,"重庆","四川","贵州","云南","西藏",null,null,null,null,null,null,"陕西","甘肃","青海","宁夏","新疆",null,null,null,null,null,"台湾",null,null,null,null,null,null,null,null,null,"香港","澳门",null,null,null,null,null,null,null,null,"国外"};<BR>&nbsp;&nbsp;&nbsp;double iSum=0;<BR>&nbsp;&nbsp;&nbsp;string info="";<BR>&nbsp;&nbsp;&nbsp;System.Text.RegularExpressions.Regex rg = new System.Text.RegularExpressions.Regex(@"^\d{17}(\d|x)$");<BR>&nbsp;&nbsp;&nbsp;System.Text.RegularExpressions.Match mc = rg.Match(cid);<BR>&nbsp;&nbsp;&nbsp;if(!mc.Success)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return "";<BR>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;cid = cid.ToLower();<BR>&nbsp;&nbsp;&nbsp;cid = cid.Replace("x","a");<BR>&nbsp;&nbsp;&nbsp;if(aCity[int.Parse(cid.Substring(0,2))]==null)<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return "非法地区";<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;try<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;DateTime.Parse(cid.Substring(6,4)+"-"+cid.Substring(10,2)+"-"+cid.Substring(12,2));<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;catch<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;return "非法生日";<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;for(int i=17;i&gt;=0;i--)<BR>&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;iSum +=(System.Math.Pow(2,i)%11)*int.Parse(cid[17-i].ToString(),System.Globalization.NumberStyles.HexNumber);</FONT></P>
<P><FONT size=5>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;if(iSum%11!=1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;return("非法证号");<BR>&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;return(aCity[int.Parse(cid.Substring(0,2))]+","+cid.Substring(6,4)+"-"+cid.Substring(10,2)+"-"+cid.Substring(12,2)+","+(int.Parse(cid.Substring(16,1))%2==1¡"男":"女"));<BR>&nbsp;&nbsp;<BR>&nbsp;&nbsp;}<BR><BR><FONT color=#ffa500>调用测试：</FONT><BR>Response.Write(CheckCidInfo("340524198002300019"));<BR>Response.Write(CheckCidInfo("34052419800101001x"));</FONT></P>
<P><FONT size=5></FONT>&nbsp;</P>
<P><FONT color=#ff0000 size=5>对于15位的身份验证可以先升至18位再进行验证，因为一直很忙，就没有写15－》18的方法<BR>把规则公布一下：</FONT></P>
<P><FONT size=5></FONT>&nbsp;</P>
<P><FONT size=5>&nbsp;&nbsp;&nbsp; 根据〖中华人民共和国国家标准 GB 11643-1999〗中有关公民身份号码的规定，公民身份号码是特征组合码，由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为：六位数字地址码，八位数字出生日期码，三位数字顺序码和一位数字校验码。 </FONT></P>
<P><FONT size=5>&nbsp;&nbsp;&nbsp; 地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。生日期码表示编码对象出生的年、月、日，其中年份用四位数字表示，年、月、日之间不用分隔符。顺序码表示同一地址码所标识的区域范围内，对同年、月、日出生的人员编定的顺序号。顺序码的奇数分给男性，偶数分给女性。校验码是根据前面十七位数字码，按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。下面举例说明该计算方法。&nbsp; </FONT></P>
<P><FONT size=5>&nbsp;&nbsp;&nbsp; 15位的身份证编码首先把出生年扩展为4位，简单的就是增加一个19，但是这对于1900年出生的人不使用（这样的寿星不多了）</FONT></P>
<P><FONT size=5>&nbsp;&nbsp;&nbsp; 某男性公民身份号码本体码为34052419800101001，首先按照公式⑴计算： </FONT></P>
<P><FONT size=5>∑(ai×Wi)(mod 11)……………………………………(1) </FONT></P>
<P><FONT size=5>公式(1)中：<BR>i----表示号码字符从由至左包括校验码在内的位置序号；<BR>ai----表示第i位置上的号码字符值；<BR>Wi----示第i位置上的加权因子，其数值依据公式Wi=2（n-1）(mod 11)计算得出。 </FONT></P>
<P><FONT size=5>i&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 18 17 16 15 14 13 12 11 10&nbsp; 9&nbsp; 8&nbsp; 7&nbsp; 6&nbsp; 5&nbsp; 4&nbsp; 3&nbsp; 2&nbsp; 1 </FONT></P>
<P><FONT size=5>ai&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp; 4&nbsp; 0&nbsp; 5&nbsp; 2&nbsp; 4&nbsp; 1&nbsp; 9&nbsp; 8&nbsp; 0&nbsp; 0&nbsp; 1&nbsp; 0&nbsp; 1&nbsp; 0&nbsp; 0&nbsp; 1 a1 </FONT></P>
<P><FONT size=5>Wi&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7&nbsp; 9 10&nbsp; 5&nbsp; 8&nbsp; 4&nbsp; 2&nbsp; 1&nbsp; 6&nbsp; 3&nbsp; 7&nbsp; 9 10&nbsp; 5&nbsp; 8&nbsp; 4&nbsp; 2&nbsp; 1 </FONT></P>
<P><FONT size=5>ai×Wi&nbsp; 21 36&nbsp; 0 25 16 16&nbsp; 2&nbsp; 9 48&nbsp; 0&nbsp; 0&nbsp; 9&nbsp; 0&nbsp; 5&nbsp; 0&nbsp; 0&nbsp; 2 a1 </FONT></P>
<P><FONT size=5>根据公式(1)进行计算： </FONT></P>
<P><FONT size=5>∑(ai×Wi) =（21+36+0+25+16+16+2+9+48++0+0+9+0+5+0+0+2) = 189 </FONT></P>
<P><FONT size=5>189 ÷ 11 = 17 + 2/11 </FONT></P>
<P><FONT size=5>∑(ai×Wi)(mod 11) = 2 </FONT></P>
<P><FONT size=5>&nbsp;&nbsp;&nbsp; 然后根据计算的结果，从下面的表中查出相应的校验码，其中X表示计算结果为10： </FONT></P>
<P><FONT size=5>∑(ai×WI)(mod 11)&nbsp;&nbsp; 0 1 2 3 4 5 6 7 8 9 10 <BR>校验码字符值ai&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 0 X 9 8 7 6 5 4 3&nbsp; 2<BR>&nbsp;&nbsp;&nbsp; 根据上表，查出计算结果为2的校验码为所以该人员的公民身份号码应该为 34052419800101001X。</FONT></P></SPAN></DIV><BR><img src ="http://www.blogjava.net/songfei/aggbug/20278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-11-17 17:24 <a href="http://www.blogjava.net/songfei/articles/20278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#中通过使用ADO.NET读写BLOB数据</title><link>http://www.blogjava.net/songfei/articles/20270.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 17 Nov 2005 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/20270.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/20270.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/20270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/20270.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/20270.html</trackback:ping><description><![CDATA[<DIV align=center>
<H1 class=aTitle>C#中通过使用ADO.NET读写BLOB数据</H1></DIV>
<TABLE width="97%" align=center>
<TBODY>
<TR>
<TD width=120>[日期：<SPAN id=TimeLabel>2005-02-12</SPAN>]</TD>
<TD align=middle><SPAN id=AuthorLabel></SPAN></TD>
<TD align=right width=100>[字体：<A href="javascript:ContentSize(16)">大</A> <A href="javascript:ContentSize(14)">中</A> <A href="javascript:ContentSize(12)">小</A>] </TD></TR></TBODY></TABLE>
<DIV class=content id=BodyLabel style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">本文引用下面的 Microsoft .NET 框架类库名称空间： 
<TABLE class=list>
<TBODY>
<TR>
<TD class=bullet>•</TD>
<TD class=text><B>System.Data.SqlClient </B></TD></TR>
<TR>
<TD class=bullet>•</TD>
<TD class=text><B>System.IO</B></TD></TR></TBODY></TABLE><A name=toc></A>
<H3>本任务的内容</H3>
<TABLE class=list>
<TBODY>
<TR>
<TD class=bullet>•</TD>
<TD class=text><A title="" href="http://www.xmlasp.net/n1393c13.aspx#1" target="">概要</A></TD></TR>
<TR>
<TD>&nbsp;</TD>
<TD class=text>
<TABLE class=list>
<TBODY>
<TR>
<TD class=bullet>•</TD>
<TD class=text><A title="" href="http://www.xmlasp.net/n1393c13.aspx#2" target="">要求</A></TD></TR>
<TR>
<TD class=bullet>•</TD>
<TD class=text><A title="" href="http://www.xmlasp.net/n1393c13.aspx#3" target="">创建项目</A></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><A name=1></A>
<DIV class=section>
<H2 class=subTitle><A name=kb1>概要</A></H2>
<DIV class=sbody>在 ADO.NET 中，<B>DataReader </B>列、<B>DataSet </B>列或<B> Command </B>参数不能使用<B> GetChunk </B>和<B> AppendChunk </B>方法。本文介绍如何使用 Visual C# .NET 读写二进制大对象 (BLOB) 字段。 <BR><BR><SPAN class=weboutput><A title="" href="http://www.xmlasp.net/n1393c13.aspx#toc" target="" name=bottom>返回页首</A></SPAN> 
<H3><A name=2></A>要求</H3>下面的列表列出了推荐使用的硬件、软件、网络结构以及所需的 Service Pack： 
<TABLE class=list>
<TBODY>
<TR>
<TD class=bullet>•</TD>
<TD class=text>Microsoft Windows 2000 Professional、Windows 2000 Server、Windows 2000 Advanced Server 或 Windows NT 4.0 Server</TD></TR>
<TR>
<TD class=bullet>•</TD>
<TD class=text>Microsoft Visual Studio .NET</TD></TR>
<TR>
<TD class=bullet>•</TD>
<TD class=text>Microsoft SQL Server</TD></TR></TBODY></TABLE><SPAN class=weboutput><A title="" href="http://www.xmlasp.net/n1393c13.aspx#toc" target="" name=bottom>返回页首</A></SPAN> 
<H3><A name=3></A>创建项目</H3>
<TABLE class=list>
<TBODY>
<TR>
<TD class=number>1.</TD>
<TD class=text>在您的 SQL Server <B>罗斯文</B>数据库中添加一个名为 MyImages 的表。在该表中包含以下字段： 
<TABLE class=list>
<TBODY>
<TR>
<TD class=bullet>•</TD>
<TD class=text>标识字段，名为"ID"，类型为 <B>Int</B>。</TD></TR>
<TR>
<TD class=bullet>•</TD>
<TD class=text>字段，名为"Description"，类型为 <B>VarChar</B>，长度为 50。</TD></TR>
<TR>
<TD class=bullet>•</TD>
<TD class=text>字段，名为"ImgField"，类型为 <B>Image</B>。</TD></TR></TBODY></TABLE><BR></TD></TR>
<TR>
<TD class=number>2.</TD>
<TD class=text>启动 Visual Studio .NET，然后新建一个 Visual C# Windows 应用程序项目。</TD></TR>
<TR>
<TD class=number>3.</TD>
<TD class=text>将两个 <B>Button</B> 控件从工具箱拖到默认窗体 Form1 上。</TD></TR>
<TR>
<TD class=number>4.</TD>
<TD class=text>在"属性"窗口中，将 <B>Button1</B> 的 <B>Text</B> 属性更改为<SPAN class=userInput>保存到数据库（从文件）</SPAN>，将 <B>Button2</B> 的 <B>Text</B> 属性更改为<SPAN class=userInput>保存到文件（从数据库）</SPAN>。</TD></TR>
<TR>
<TD class=number>5.</TD>
<TD class=text>将下面的代码添加到"代码"窗口顶部： <CODE><PRE class=code>using System.Data;
using System.Data.SqlClient;
using System.IO;</PRE></CODE></TD></TR>
<TR>
<TD class=number>6.</TD>
<TD class=text>双击 <B>Button1</B>，然后将以下代码添加到 <B>Button1_Click</B> 事件处理程序中： <CODE><PRE class=code>{
SqlConnection con = new SqlConnection("Server=Darkover;uid=sa;pwd=Password1;database=northwind");
SqlDataAdapter da = new SqlDataAdapter("Select * From MyImages", con);
SqlCommandBuilder MyCB = new SqlCommandBuilder(da);
DataSet ds = new DataSet("MyImages");

da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
FileStream fs = new FileStream(@"C:\winnt\Gone Fishing.BMP", FileMode.OpenOrCreate, FileAccess.Read);

byte[] MyData= new byte[fs.Length];
fs.Read(MyData, 0, System.Convert.ToInt32(fs.Length));

fs.Close();

da.Fill(ds,"MyImages");

DataRow myRow;
myRow=ds.Tables["MyImages"].NewRow();

myRow["Description"] = "This would be description text";
myRow["imgField"] = MyData;
ds.Tables["MyImages"].Rows.Add(myRow);
da.Update(ds, "MyImages");

con.Close();

}</PRE></CODE></TD></TR>
<TR>
<TD class=number>7.</TD>
<TD class=text>双击 <B>Button2</B>，然后将以下代码添加到 <B>Button2_Click</B> 事件处理程序中： <CODE><PRE class=code>{
SqlConnection con = new SqlConnection("Server=Darkover;uid=sa;pwd=Password1;database=northwind");
SqlDataAdapter da = new SqlDataAdapter("Select * From MyImages", con);
SqlCommandBuilder MyCB = new SqlCommandBuilder(da);
DataSet ds = new DataSet("MyImages");

byte[] MyData= new byte[0];

da.Fill(ds, "MyImages");
DataRow myRow;
myRow=ds.Tables["MyImages"].Rows[0];

MyData =  (byte[])myRow["imgField"];
int ArraySize = new int();
ArraySize = MyData.GetUpperBound(0);

FileStream fs = new FileStream(@"C:\winnt\Gone Fishing2.BMP", FileMode.OpenOrCreate, FileAccess.Write);
fs.Write(MyData, 0,ArraySize);
fs.Close();
}</PRE></CODE></TD></TR>
<TR>
<TD class=number>8.</TD>
<TD class=text>按 F5 键编译并运行该应用程序。</TD></TR>
<TR>
<TD class=number>9.</TD>
<TD class=text>单击"<STRONG class=uiterm>保存到数据库（从文件）</STRONG>"，将位于 C:\WinNT\Gone Fishing.bmp 的图像加载到 SQL Server <B>Image</B> 字段。</TD></TR>
<TR>
<TD class=number>10.</TD>
<TD class=text>单击"<STRONG class=uiterm>保存到文件（从数据库）</STRONG>"，将 SQL Server <B>Image</B> 字段的数据保存回文件中。</TD></TR></TBODY></TABLE></DIV></DIV></DIV><img src ="http://www.blogjava.net/songfei/aggbug/20270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-11-17 17:03 <a href="http://www.blogjava.net/songfei/articles/20270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VB C# 语法对比图 </title><link>http://www.blogjava.net/songfei/articles/20268.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Thu, 17 Nov 2005 08:55:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/20268.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/20268.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/20268.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/20268.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/20268.html</trackback:ping><description><![CDATA[<DIV align=center>
<H1 class=aTitle>VB C# 语法对比图 (代码实例)</H1></DIV>
<TABLE width="97%" align=center>
<TBODY>
<TR>
<TD width=120></TD>
<TD align=middle><SPAN id=AuthorLabel></SPAN></TD>
<TD align=right width=100>[字体：<A href="javascript:ContentSize(16)">大</A> <A href="javascript:ContentSize(14)">中</A> <A href="javascript:ContentSize(12)">小</A>] </TD></TR></TBODY></TABLE>
<DIV class=content id=BodyLabel style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">
<P>C#和VB.net的语法相差还是比较大的. 可能你会C#,可能你会VB.</P>
<P>将它们俩放在一起对比一下你就会很快读懂,并掌握另一门语言.</P>
<P>相信下面这张图会对你帮助很大.</P>
<P>
<TABLE style="TABLE-LAYOUT: fixed" height=8964 cellPadding=5 width=550 border=1>
<TBODY>
<TR>
<TD colSpan=2>&nbsp;</TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Comments</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Single line only
Rem Single line only</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P><PRE>// Single line
/* Multiple
line */
/// XML comments on single line
/** XML comments on multiple lines */</PRE></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Data Types</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Value Types
Boolean
Byte
Char (example: "A")
Short, Integer, Long
Single, Double
Decimal
Date 


'Reference Types
Object
String



Dim x As Integer
System.Console.WriteLine(x.GetType())
System.Console.WriteLine(TypeName(x)) 


'Type conversion
Dim d As Single = 3.5
Dim i As Integer = CType (d, Integer)
i = CInt (d)
i = Int(d)</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>//Value Types
bool
byte, sbyte
char (example: 'A')
short, ushort, int, uint, long, ulong
float, double
decimal
DateTime 


//Reference Types
object
string



int x;
Console.WriteLine(x.GetType())
Console.WriteLine(typeof(int)) 


//Type conversion
float d = 3.5;
int i = (int) d</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Constants</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P><PRE>Const MAX_AUTHORS As Integer = 25
ReadOnly MIN_RANK As Single = 5.00</PRE></TD>
<TD>
<P><STRONG>C#</STRONG></P><PRE>const int MAX_AUTHORS = 25;
readonly float MIN_RANKING = 5.00;</PRE></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Enumerations</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P><PRE>Enum Action
&nbsp;&nbsp;Start
&nbsp;&nbsp;'Stop is a reserved word
[Stop]
&nbsp;&nbsp;Rewind
&nbsp;&nbsp;Forward
End Enum

Enum Status
&nbsp;&nbsp; Flunk = 50
&nbsp;&nbsp; Pass = 70
&nbsp;&nbsp; Excel = 90
End Enum

Dim a As Action = Action.Stop 
If a &lt;&gt; Action.Start Then _
'Prints "Stop is 1" 
&nbsp; &nbsp;System.Console.WriteLine(a.ToString &amp; " is " &amp; a)

'Prints 70
System.Console.WriteLine(Status.Pass)
'Prints Pass
System.Console.WriteLine(Status.Pass.ToString())</PRE></TD>
<TD>
<P><STRONG>C#</STRONG></P><PRE>enum Action {Start, Stop, Rewind, Forward};
enum Status {Flunk = 50, Pass = 70, Excel = 90};











Action a = Action.Stop;
if (a != Action.Start)
//Prints "Stop is 1"
&nbsp; System.Console.WriteLine(a + " is " + (int) a); 

// Prints 70
System.Console.WriteLine((int) Status.Pass); 
// Prints Pass
System.Console.WriteLine(Status.Pass);</PRE></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Operators</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Comparison
=&nbsp; &lt;&nbsp; &gt;&nbsp; &lt;=&nbsp; &gt;=&nbsp; &lt;&gt; 


'Arithmetic
+&nbsp; -&nbsp; *&nbsp; /
Mod
&nbsp; (integer division)
^&nbsp; (raise to a power) 


'Assignment
=&nbsp; +=&nbsp; -=&nbsp; *=&nbsp; /=&nbsp; = &nbsp;^=&nbsp; &lt;&lt;= &nbsp;&gt;&gt;=&nbsp; &amp;= 


'Bitwise
And&nbsp;&nbsp;AndAlso&nbsp; Or&nbsp;&nbsp;OrElse&nbsp; Not&nbsp; &lt;&lt;&nbsp; &gt;&gt; 


'Logical
And&nbsp; AndAlso&nbsp; Or&nbsp;&nbsp;OrElse&nbsp;&nbsp;Not 


'String Concatenation
&amp; </PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>//Comparison
==&nbsp; &lt;&nbsp; &gt;&nbsp; &lt;=&nbsp; &gt;=&nbsp; != 


//Arithmetic
+&nbsp; -&nbsp; *&nbsp; /
%&nbsp; (mod)
/&nbsp; (integer division if both operands are ints)
Math.Pow(x, y) 


//Assignment
=&nbsp; +=&nbsp; -= &nbsp;*=&nbsp; /= &nbsp; %=&nbsp; &amp;=&nbsp; |=&nbsp; ^=&nbsp; &lt;&lt;=&nbsp; &gt;&gt;=&nbsp; ++&nbsp; -- 


//Bitwise
&amp; &nbsp;| &nbsp;^&nbsp;&nbsp;&nbsp;~&nbsp; &lt;&lt;&nbsp; &gt;&gt; 


//Logical
&amp;&amp;&nbsp; ||&nbsp;&nbsp; ! 


//String Concatenation
+</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Choices</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>greeting = IIf(age &lt; 20, "What's up?", "Hello") 


'One line doesn't require "End If", no "Else"
If language = "VB.NET" Then langType = "verbose" 


'Use: to put two commands on same line
If x &lt;&gt; 100 And y &lt; 5 Then x *= 5 : y *= 2&nbsp;&nbsp; 


'Preferred
If x &lt;&gt; 100 And y &lt; 5 Then
&nbsp; x *= 5
&nbsp; y *= 2
End If 




'or to break up any long single command use _
If henYouHaveAReally &lt;&nbsp;longLine And _ 
itNeedsToBeBrokenInto2 &nbsp; &gt; Lines &nbsp;Then _
&nbsp; UseTheUnderscore(charToBreakItUp) 


If x &gt; 5 Then
&nbsp; x *= y 
ElseIf x = 5 Then
&nbsp; x += y 
ElseIf x &lt; 10 Then
&nbsp; x -= y
Else
&nbsp; x /= y
End If 


'Must be a primitive data type
Select Case color &nbsp;&nbsp;
&nbsp; Case "black", "red"
&nbsp;&nbsp;&nbsp; r += 1
&nbsp; Case "blue"
&nbsp;&nbsp;&nbsp; b += 1
&nbsp; Case "green"
&nbsp;&nbsp;&nbsp; g += 1
&nbsp; Case Else
&nbsp;&nbsp;&nbsp; other += 1
End Select</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>greeting = age &lt; 20 ? "What's up?" : "Hello"; 











if (x != 100 &amp;&amp; y &lt; 5)
{
&nbsp; // Multiple statements must be enclosed in {}
&nbsp; x *= 5;
&nbsp; y *= 2;
} 








if (x &gt; 5) 
&nbsp; x *= y; 
else if (x == 5) 
&nbsp; x += y; 
else if (x &lt; 10) 
&nbsp; x -= y; 
else 
&nbsp; x /= y;



//Must be integer or string
switch (color)
{
&nbsp; case "black":
&nbsp; case "red":&nbsp;&nbsp;&nbsp; r++;
&nbsp;&nbsp; break;
&nbsp; case "blue"
&nbsp;&nbsp; break;
&nbsp; case "green": g++;&nbsp;&nbsp;
&nbsp;&nbsp; break;
&nbsp; default:&nbsp;&nbsp;&nbsp; other++;
&nbsp;&nbsp; break;
}</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Loops</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Pre-test Loops:
While c &lt; 10
&nbsp; c += 1
End While Do Until c = 10
&nbsp; c&nbsp;+= 1
Loop 


'Post-test Loop:
Do While c &lt; 10
&nbsp; c += 1
Loop 


For c = 2 To 10 Step 2
&nbsp; System.Console.WriteLine(c)
Next 



'Array or collection looping
Dim names As String() = {"Steven", "SuOk", "Sarah"}
For Each s As String In names
&nbsp; System.Console.WriteLine(s)
Next</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P><PRE>//Pre-test Loops: while (i &lt; 10)
&nbsp; i++;
for (i = 2; i &lt; = 10; i += 2)
&nbsp; System.Console.WriteLine(i); 






//Post-test Loop:
do
&nbsp; i++;
while (i &lt; 10);








// Array or collection looping
string[] names = {"Steven", "SuOk", "Sarah"};
foreach (string s in names)
&nbsp; System.Console.WriteLine(s);</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Arrays</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Dim nums() As Integer = {1, 2, 3}
For i As Integer = 0 To nums.Length - 1 
&nbsp; Console.WriteLine(nums(i)) 
Next 

'4 is the index of the last element, so it holds 5 elements
Dim names(4) As String
names(0) = "Steven"
'Throws System.IndexOutOfRangeException
names(5) = "Sarah"


'Resize the array, keeping the existing
'values (Preserve is optional)
ReDim Preserve names(6)





Dim twoD(rows-1, cols-1) As Single 
twoD(2, 0) = 4.5


Dim jagged()() As Integer = { _
&nbsp; New Integer(4) {}, New Integer(1) {}, New Integer(2) {} }
jagged(0)(4) = 5</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>int[] nums = {1, 2, 3};
for (int i = 0; i &lt; nums.Length; i++)
&nbsp; Console.WriteLine(nums[i]);


// 5 is the size of the array
string[] names = new string[5];
names[0] = "Steven";
// Throws System.IndexOutOfRangeException
names[5] = "Sarah"


// C# can't dynamically resize an array.
//Just copy into new array.
string[] names2 = new string[7];
// or names.CopyTo(names2, 0);
Array.Copy(names, names2, names.Length); 



float[,] twoD = new float[rows, cols];
twoD[2,0] = 4.5; 


int[][] jagged = new int[3][] {
&nbsp; new int[5], new int[2], new int[3] };
jagged[0][4] = 5;</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Functions</STRONG></P></TD></TR>
<TR>
<TD width="50%">
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Pass by value (in, default), reference
'(in/out), and reference (out)
Sub TestFunc(ByVal x As Integer, ByRef y As Integer,
ByRef z As Integer)
&nbsp; x += 1
&nbsp; y += 1
&nbsp; z = 5
End Sub 


'c set to zero by default

Dim a = 1, b = 1, c As Integer
TestFunc(a, b, c)
System.Console.WriteLine("{0} {1} {2}", a, b, c) '1 2 5 


'Accept variable number of arguments
Function Sum(ByVal ParamArray nums As Integer()) As Integer
&nbsp; Sum = 0
&nbsp; For Each i As Integer In nums
&nbsp;&nbsp;&nbsp; Sum += i
&nbsp; Next
End Function 'Or use a Return statement like C#

Dim total As Integer = Sum(4, 3, 2, 1) 'returns 10 


'Optional parameters must be listed last
'and must have a default value
Sub SayHello(ByVal name As String,
Optional ByVal prefix As String = "")
&nbsp;&nbsp;System.Console.WriteLine("Greetings, " &amp; prefix
&amp; " " &amp; name)
End Sub


SayHello("Steven", "Dr.")
SayHello("SuOk")</PRE><BR>
<P>&nbsp;</P></TD>
<TD width="50%">
<P><STRONG>C#</STRONG></P><PRE>// Pass by value (in, default), reference
//(in/out), and reference (out)
void TestFunc(int x, ref int y, out int z) {
&nbsp; x++;
&nbsp; y++;
&nbsp; z = 5;
} 




int a = 1, b = 1, c; // c doesn't need initializing
TestFunc(a, ref b, out c);
System.Console.WriteLine("{0} {1} {2}", a, b, c); // 1 2 5 


// Accept variable number of arguments
int Sum(params int[] nums) {
&nbsp; int sum = 0;
&nbsp; foreach (int i in nums)
&nbsp;&nbsp;&nbsp; sum += i;
&nbsp; return sum;
} 


int total = Sum(4, 3, 2, 1); // returns 10 


/* C# doesn't&nbsp;support optional arguments/parameters.
Just create two different versions of the same function. */
void SayHello(string name, string prefix) {
&nbsp; System.Console.WriteLine("Greetings, " <BR>	+ prefix + " " + name);
}

void SayHello(string name) {
&nbsp; SayHello(name, "");
}</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Exception Handling</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Deprecated unstructured error handling
On Error GoTo MyErrorHandler
...
MyErrorHandler: System.Console.WriteLine(Err.Description)

Dim ex As New Exception("Something has really gone wrong.")
Throw ex 


Try
&nbsp; y = 0
&nbsp; x = 10 / y
Catch ex As Exception When y = 0 'Argument and When is optional
&nbsp; System.Console.WriteLine(ex.Message) 
Finally
&nbsp; DoSomething() 
End Try</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P><BR><BR><BR><BR></P><PRE>Exception up = new Exception("Something is really wrong."); 
throw up; // ha ha 


try{
&nbsp; y = 0;
&nbsp; x = 10 / y;
}
catch (Exception ex) { //Argument is optional, no "When" keyword
&nbsp; Console.WriteLine(ex.Message);
}
finally{
&nbsp; // Do something
}</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Namespaces</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Namespace ASPAlliance.DotNet.Community
&nbsp; ...
End Namespace 


'or 


Namespace ASPAlliance 
&nbsp; Namespace DotNet
&nbsp;&nbsp;&nbsp; Namespace Community
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...
&nbsp;&nbsp;&nbsp; End Namespace
&nbsp; End Namespace
End Namespace 


Imports ASPAlliance.DotNet.Community</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>namespace ASPAlliance.DotNet.Community {
&nbsp; ...
} 


// or 


namespace ASPAlliance {
&nbsp; namespace DotNet {
&nbsp;&nbsp;&nbsp; namespace Community {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...
&nbsp;&nbsp;&nbsp; }
&nbsp; }
} 


using ASPAlliance.DotNet.Community;</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Classes / Interfaces</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Accessibility keywords
Public
Private
Friend
Protected
Protected Friend
Shared 


'Inheritance
Class Articles
&nbsp; Inherits Authors
&nbsp; ...
End Class 


'Interface definition
Interface IArticle&nbsp;
&nbsp; ...
End Interface 


'Extending an interface
Interface IArticle
&nbsp; Inherits IAuthor
&nbsp; ...
End Interface 


'Interface implementation&lt;/span&gt;
Class PublicationDate
&nbsp; Implements&lt;/strong&gt; IArticle, IRating
&nbsp;&nbsp; ...
End Class</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>//Accessibility keywords
public
private
internal
protected
protected internal
static 


//Inheritance
class Articles: Authors {
&nbsp; ...
} 



//Interface definition
interface IArticle {
&nbsp; ...
} 


//Extending an interface
interface IArticle: IAuthor {
&nbsp; ...
} 



//Interface implementation
class PublicationDate: IArticle, IRating {
&nbsp;&nbsp; ...
}</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Constructors / Destructors</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P><PRE>Class TopAuthor
&nbsp; Private _topAuthor As Integer

&nbsp; Public Sub New()
&nbsp;&nbsp;&nbsp; _topAuthor = 0
&nbsp; End Sub

&nbsp; Public Sub New(ByVal topAuthor As Integer)
&nbsp;&nbsp;&nbsp; Me._topAuthor = topAuthor
&nbsp; End Sub

&nbsp; Protected Overrides Sub Finalize()
&nbsp;&nbsp;&nbsp;'Desctructor code to free unmanaged resources
&nbsp;&nbsp;&nbsp; MyBase.Finalize() 
&nbsp; End Sub
End Class</PRE></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>class TopAuthor {
&nbsp; private int _topAuthor;

&nbsp; public TopAuthor() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_topAuthor = 0;
&nbsp; }

&nbsp; public TopAuthor(int topAuthor) {
&nbsp;&nbsp;&nbsp; this._topAuthor= topAuthor
&nbsp; }

&nbsp; ~TopAuthor() {
&nbsp;&nbsp;&nbsp; // Destructor code to free unmanaged resources.
&nbsp;&nbsp;&nbsp; // Implicitly creates a Finalize method
&nbsp; }
}</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Objects</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Dim author As TopAuthor = New TopAuthor
With author
&nbsp; .Name = "Steven"
&nbsp; .AuthorRanking = 3
End With

author.Rank("Scott")
author.Demote() 'Calling Shared method
'or
TopAuthor.Rank() 


Dim author2 As TopAuthor = author 'Both refer to same object
author2.Name = "Joe"
System.Console.WriteLine(author2.Name) 'Prints Joe 


author = Nothing 'Free the object 


If author Is Nothing Then _
&nbsp; author = New TopAuthor 


Dim obj As Object = New TopAuthor
If TypeOf obj Is TopAuthor Then _
&nbsp; System.Console.WriteLine("Is a TopAuthor object.")</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>TopAuthor author = new TopAuthor();

//No "With" construct
author.Name = "Steven";
author.AuthorRanking = 3; 


author.Rank("Scott");
TopAuthor.Demote() //Calling static method 




TopAuthor author2 = author //Both refer to same object
author2.Name = "Joe";
System.Console.WriteLine(author2.Name) //Prints Joe 


author = null //Free the object 


if (author == null)
&nbsp; author = new TopAuthor(); 


Object obj = new TopAuthor();&nbsp;
if (obj is TopAuthor)
&nbsp; SystConsole.WriteLine("Is a TopAuthor object.");</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Structs</STRONG></P></TD></TR>
<TR>
<TD>
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Structure AuthorRecord
&nbsp; Public name As String
&nbsp; Public rank As Single

&nbsp; Public Sub New(ByVal name As String, ByVal rank As Single) 
&nbsp;&nbsp;&nbsp; Me.name = name
&nbsp;&nbsp;&nbsp; Me.rank = rank
&nbsp; End Sub
End Structure 


Dim author As AuthorRecord = New AuthorRecord("Steven", 8.8)
Dim author2 As AuthorRecord = author

author2.name = "Scott"
System.Console.WriteLine(author.name) 'Prints Steven
System.Console.WriteLine(author2.name) 'Prints Scott</PRE>
<P>&nbsp;</P></TD>
<TD>
<P><STRONG>C#</STRONG></P><PRE>struct AuthorRecord {
&nbsp; public string name;
&nbsp; public float rank;

&nbsp; public AuthorRecord(string name, float rank) {
&nbsp;&nbsp;&nbsp; this.name = name;
&nbsp;&nbsp;&nbsp; this.rank = rank;
&nbsp; }
}



AuthorRecord author = new AuthorRecord("Steven", 8.8);
AuthorRecord author2 = author

author.name = "Scott";
SystemConsole.WriteLine(author.name); //Prints Steven
System.Console.WriteLine(author2.name); //Prints Scott</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Properties</STRONG></P></TD></TR>
<TR>
<TD width="50%">
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Private _size As Integer

Public Property Size() As Integer
&nbsp; Get
&nbsp;&nbsp; &nbsp;Return _size
&nbsp; End Get
&nbsp; Set (ByVal Value As Integer)
&nbsp;&nbsp;&nbsp; If Value &lt; 0 Then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _size = 0
&nbsp;&nbsp;&nbsp; Else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _size = Value
&nbsp;&nbsp;&nbsp; End If
&nbsp; End Set
End Property 


foo.Size += 1</PRE>
<P>&nbsp;</P></TD>
<TD width="50%">
<P><STRONG>C#</STRONG></P><PRE>private int _size;

public int Size {
&nbsp; get {
&nbsp;&nbsp;&nbsp; return _size;
&nbsp; }
&nbsp; set {
&nbsp; &nbsp; if (value &lt; 0)
&nbsp; &nbsp; &nbsp; _size = 0;
&nbsp; &nbsp; else
&nbsp; &nbsp; &nbsp; _size = value;
&nbsp; }
} 



foo.Size++;</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Delegates / Events</STRONG></P></TD></TR>
<TR>
<TD width="50%">
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Delegate Sub MsgArrivedEventHandler(ByVal message
As String) 


Event MsgArrivedEvent As MsgArrivedEventHandler 


'or to define an event which declares a
'delegate implicitly
Event MsgArrivedEvent(ByVal message As String) 


AddHandler MsgArrivedEvent, AddressOf My_MsgArrivedCallback
'Won't throw an exception if obj is Nothing
RaiseEvent MsgArrivedEvent("Test message")
RemoveHandler MsgArrivedEvent, AddressOf My_MsgArrivedCallback



Imports System.Windows.Forms 


'WithEvents can't be used on local variable
Dim WithEvents MyButton As Button
MyButton = New Button 


Private Sub MyButton_Click(ByVal sender As System.Object, _
&nbsp; ByVal e As System.EventArgs) Handles MyButton.Click
&nbsp; MessageBox.Show(Me, "Button was clicked", "Info", _
&nbsp;&nbsp;&nbsp; MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub</PRE>
<P>&nbsp;</P></TD>
<TD width="50%">
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>delegate void MsgArrivedEventHandler(string message); 


event MsgArrivedEventHandler MsgArrivedEvent; 


//Delegates must be used with events in C#


MsgArrivedEvent += new MsgArrivedEventHandler
&nbsp;&nbsp;(My_MsgArrivedEventCallback);
//Throws exception if obj is null
MsgArrivedEvent("Test message");
MsgArrivedEvent -= new MsgArrivedEventHandler
&nbsp;&nbsp;(My_MsgArrivedEventCallback); 



using System.Windows.Forms; 


Button MyButton = new Button();
MyButton.Click += new System.EventHandler(MyButton_Click); 


private void MyButton_Click(object sender, <BR>			System.EventArgs e) {
&nbsp; MessageBox.Show(this, "Button was clicked", "Info",
&nbsp;&nbsp;&nbsp; MessageBoxButtons.OK, MessageBoxIcon.Information);
}</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>Console I/O</STRONG></P></TD></TR>
<TR>
<TD width="50%">
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>'Special character constants
vbCrLf, vbCr, vbLf, vbNewLine
vbNullString
vbTab
vbBack
vbFormFeed
vbVerticalTab
""
Chr(65) 'Returns 'A' 


System.Console.Write("What's your name? ")
Dim name As String = System.Console.ReadLine()
System.Console.Write("How old are you? ")
Dim age As Integer = Val(System.Console.ReadLine())
System.Console.WriteLine("{0} is {1} years old.", name, age)
'or
System.Console.WriteLine(name &amp; " is " &amp; age &amp; " years old.")

Dim c As Integer
c = System.Console.Read() 'Read single char
System.Console.WriteLine(c) 'Prints 65 if user enters "A"</PRE>
<P>&nbsp;</P></TD>
<TD width="50%">
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>//Escape sequences
n, r
t

 


Convert.ToChar(65) <BR>//Returns 'A' - equivalent to Chr(num) in VB
// or
(char) 65 


System.Console.Write("What's your name? ");
string name = SYstem.Console.ReadLine();
System.Console.Write("How old are you? ");
int age = Convert.ToInt32(System.Console.ReadLine());
System.Console.WriteLine("{0} is {1} years old.", <BR>	name, age);
//or
System.Console.WriteLine(name + " is " + <BR>	age + " years old."); 


int c = System.Console.Read(); //Read single char
System.Console.WriteLine(c); <BR>//Prints 65 if user enters "A"</PRE>
<P>&nbsp;</P></TD></TR>
<TR>
<TD colSpan=2>
<P align=center><STRONG>File I/O</STRONG></P></TD></TR>
<TR>
<TD width="50%">
<P><STRONG>VB.NET</STRONG></P>
<P>&nbsp;</P><PRE>Imports System.IO 


'Write out to text file
Dim writer As StreamWriter = File.CreateText
&nbsp;&nbsp;("c:myfile.txt")
writer.WriteLine("Out to file.")
writer.Close() 


'Read all lines from text file
Dim reader As StreamReader = File.OpenText
&nbsp;&nbsp;("c:myfile.txt")
Dim line As String = reader.ReadLine()
While Not line Is Nothing
&nbsp; Console.WriteLine(line)
&nbsp; line = reader.ReadLine()
End While
reader.Close() 


'Write out to binary file
Dim str As String = "Text data"
Dim num As Integer = 123
Dim binWriter As New BinaryWriter(File.OpenWrite
&nbsp;&nbsp;("c:myfile.dat"))
binWriter.Write(str)
binWriter.Write(num)
binWriter.Close() 


'Read from binary file
Dim binReader As New BinaryReader(File.OpenRead
&nbsp;&nbsp;("c:myfile.dat"))
str = binReader.ReadString()
num = binReader.ReadInt32()
binReader.Close()</PRE>
<P>&nbsp;</P></TD>
<TD width="50%">
<P><STRONG>C#</STRONG></P>
<P>&nbsp;</P><PRE>using System.IO; 


//Write out to text file
StreamWriter writer = File.CreateText
&nbsp;&nbsp;("c:myfile.txt");
writer.WriteLine("Out to file.");
writer.Close(); 


//Read all lines from text file
StreamReader reader = File.OpenText
&nbsp;&nbsp;("c:myfile.txt");
string line = reader.ReadLine();
while (line != null) {
&nbsp; Console.WriteLine(line);
&nbsp; line = reader.ReadLine();
}
reader.Close(); 


//Write out to binary file
string str = "Text data";
int num = 123;
BinaryWriter binWriter = new BinaryWriter(File.OpenWrite
&nbsp;&nbsp;("c:myfile.dat"));
binWriter.Write(str);
binWriter.Write(num);
binWriter.Close(); 


//Read from binary file
BinaryReader binReader = new BinaryReader(File.OpenRead
&nbsp;&nbsp;("c:myfile.dat"));
str = binReader.ReadString();
num = binReader.ReadInt32();
binReader.Close();</PRE>
<P>&nbsp;</P></TD></TR></TBODY></TABLE></P></DIV><img src ="http://www.blogjava.net/songfei/aggbug/20268.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-11-17 16:55 <a href="http://www.blogjava.net/songfei/articles/20268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C# 中的 cookie 编程 </title><link>http://www.blogjava.net/songfei/articles/19770.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Mon, 14 Nov 2005 13:36:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/19770.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/19770.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/19770.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/19770.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/19770.html</trackback:ping><description><![CDATA[<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>C# 中的 cookie 编程 <BR>&nbsp;<BR>作者：邱燕菱&nbsp;&nbsp;&nbsp; 文章来源：本站原创&nbsp;&nbsp;&nbsp; 点击数：&nbsp;&nbsp;&nbsp; 更新时间：2005-11-8 <BR>&nbsp;<BR>Cookie就是所谓的“小甜饼“ ,他最早出现是在Netscape Navigator 2.0中。Cookie其实就是由Web服务器创建的、将信息存储在计算机上的文件。那么为什么Web服务器要在客户机上面创建如此文件？这是因为当客户机发送一个请求到WEB服务器时（譬如准备浏览页面时），无论此客户机是否是第一次来访，服务器都会把它当作第一次来对待，WEB服务器所做的工作只是简单的进行响应，然后就关闭与该用户的连接。这样处理过程所带来的缺点时显而易见的。自从网景公司开发出Cookie以后，就可以利用Cookie来保存用户的识别信息。Cookie的作用可以记录了您在该站点上曾经访问过的页面，由此帮助您下次访问该站点时自定义查看。Cookies 也可以存储个人可识别信息。个人可识别信息是可以用来识别或联系您的信息，例如姓名、电子邮件地址、家庭或工作地址，或者电话号码。然而，网站只能访问您提供的个人可识别信息。例如，除非您提供电子邮件名称，否则网站将不能确定您的电子邮件名称。另外，网站不能通过Cookie来访问计算机上的其他信息。当然除非你提供。那么Cookie到底存放在什么地方？如果机器的系统是视窗98且安装在“ C“ 盘中，那么Cookie存放在“ C:\Windows\Cookies“ 目录中；如果机器系统是视窗2000且安装在“ C“ 盘中，那么Cookie存放在“ C:\Documents and Settings\Administrator\Cookies“ 目录中。了解了Cookie这么多知识，我们还是来了解一下本文的重点-- C#是如何进行Cookie方面编程的。主要内容有二点：其一是 C#是如何写入Cookie；其二是 C#是如何访问自己写入的Cookie。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>一、本文介绍的程序设计和运行的软件环境：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>微软公司视窗2000服务器版<BR>.Net FrameWork SDK Beta 2</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>C#进行Cookie方面编程是通过ASP.NET页面来实现的。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>二、C#如何写入Cookie：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>为了写入Cookie，他的步骤主要有三步，具体如下：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>首先就要创建一个HttpCookie对象，通过这个对象来构造一个Cookie，这个对象的名称就是以后产生的Cookie名称。具体如下代码：<BR>HttpCookie cookie = new HttpCookie ( “ 用户定义的Cookie名称“ ) ;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>然后对创建的HttpCookie对象的“ Value“ 属性分配一个字符串值，“ Value“ 的值就是后来产生的Cookie的值。具体代码如下：<BR>cookie.Value = “用户给Cookie赋值“ ; 如果你想写入的Cookie数值不是一个简单的字符串，而是一个复杂的数据类型，我们知道这些数据类型是不能直接存贮到Cookie中的，因为Cookie中只能存贮字符串。但你可以通过一个变通的方法，就是把这个复杂的数据类型转换成多个字符串，然后把这多个字符串同时赋值给产生的Cookie值，这样Cookie中的内容就丰富了，以后利用Cookie完成的功能也强大了。这时你可能就会明白为什么当你浏览Web服务器，Web服务器会知道你什么时候曾经浏览过，并且曾经待过多长时间等信息了。因为这些信息已经存储到你第一次浏览页面时，Web服务器产生的Cookie中去了。下列代码是把多个字符串存储到Cookie的例子：<BR>cookie [ “ 姓名“ ] = “ 王天“;<BR>cookie [ “ 性别“ ] = “ 男“;<BR>cookie [ “ 年龄“ ] = “ 26“;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>Cookie有临时的，也有永远的。永久 Cookie 以文件形式存储在计算机上，关闭 Internet Explorer 时仍然保留在计算机上。再次访问该站点时，创建该 Cookie 的网站可以读取。在具体的编程时候，是在写入此Cookie的时候，设定Cookie的生命周期，具体如下代码：<BR>DateTime dtNow = DateTime . Now ;<BR>TimeSpan tsMinute = new TimeSpan ( 0 , 1 , 0 , 0 ) ;<BR>cookie . Expires = dtNow + tsMinute ;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>以上代码是设定产生的Cookie的生命期为“ 一个小时“ ，你可以通过修改“ TimeSpan“ 属性来设定产生Cookie的具体生命期。<BR>.最后调用“ Response.Cookies“ 对象的“ Add（）“ 方法，加入此对象，这样就可以产生一个Cookie了。具体代码如下：<BR>Response . Cookies . Add ( cookie ) ;<BR>下列代码就是在 C#写入Cookie的完整代码（Write.aspx）：<BR>〈% @ language = “C#“ %〉<BR>〈script runat = “server“ 〉<BR>void WriteClicked ( Object Sender , EventArgs e )<BR>{<BR>//创建一个HttpCookie对象<BR>HttpCookie cookie = new HttpCookie ( NameField . Text ) ;<BR>//设定此cookies值<BR>cookie . Value = ValueField . Text ;<BR>//设定cookie的生命周期，在这里定义为一个小时<BR>DateTime dtNow = DateTime . Now ;<BR>TimeSpan tsMinute = new TimeSpan ( 0 , 1 , 0 , 0 ) ;<BR>cookie . Expires = dtNow + tsMinute ;<BR>cookie [ “姓名“ ] = “王天“ ;<BR>cookie [ “性别“ ] = “男“ ;<BR>cookie [ “年龄“ ] = “26“ ;<BR>//加入此cookie<BR>Response . Cookies . Add ( cookie ) ;<BR>Response . Write ( NameField . Text + “Cookie创建完毕 〈br 〉 〈hr 〉 “ ) ;<BR>}<BR>〈/script 〉<BR>〈html 〉<BR>〈body 〉<BR>〈h3 〉 在 C#页面中创建cookie 〈/h3 〉<BR>此cookie的生命周期定义为一个小时<BR>〈form runat=“server“〉<BR>Cookie名称：〈asp:textbox id = “NameField“ runat = “server“ /〉 〈br 〉<BR>Cookie的值：〈asp:textbox id = “ValueField“ runat = “server“ /〉 〈br 〉<BR>〈asp:button text = “创建Cookie“ onclick = “WriteClicked“ runat = “server“ /〉 〈br 〉<BR>〈/form 〉<BR>〈/body 〉<BR>〈/html 〉</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>当然上面的代码产生的Cookie在内容上面有点单调了。其实对于内容十分丰富的Cookie来说，他还有许多属性，充分的利用这些属性，才可以利用了Cookie的强大功能。下表是Cookie的一些常用的属性：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>属性 描述<BR>Domain 设定/获得Cookie应属于的域名。一旦设定了此属性，则只限定于此域名的Web服务器访问此Cookie。可以设定为“ccw.com.cn“<BR>Path 设定/获得Cookie应属于的路径，如果设定后，则访问此Cookie的Web页面则被限定在此路径里面。其他路径的Web页面则不能访问。<BR>Secure 设定/获得一个标识来表明利用HTTP协议是否能够安全的传输Cookie到客户端的浏览器。<BR>HasKeys 表明是否此Cookie是否是多个字符串组成的。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>在写入Cookie的时候，最大限度的利用这些属性，对于最大程度的利用写入的Cookie是十分重要的。</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>三、C#是如何读取已产生的Cookie：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>读取指定的Cookie比起写入Cookie要来的容易的多了，只需要使用“ Request.Cookies“ 对象就可以完成。下面是读取指定Cookie名称的方法：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>HttpCookie cookie = Request.Cookies [ “ Cookie的名称“ ] ;</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>下面是显示已经读取了的Cookie的数值：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>Response.Write (cookie . Value . ToString ( ) ) ; 掌握了上面的要点，读取Cookie就显得非常容易了，下列是读取Cookie的程序代码（read.aspx）： 〈% @ language = “C#“ %〉<BR>〈script runat = “server“ 〉<BR>void ReadClicked ( Object Sender , EventArgs e )<BR>{<BR>//得到用户输入的cookie名称<BR>String strCookieName = NameField . Text ;<BR>//获得cookie<BR>HttpCookie cookie = Request.Cookies [ strCookieName ] ;<BR>//确定是否存在用户输入的cookie<BR>if ( null == cookie ) {<BR>Response.Write ( “没有发现指定的cookie 〈br 〉 〈hr 〉 “ ) ;<BR>}<BR>else {<BR>//找到指定的cookie，显示cookie的值<BR>String strCookieValue = cookie . Value . ToString ( ) ;<BR>Response.Write ( strCookieName + “ cookie 的值为: 〈b 〉 “<BR>+ strCookieValue + “ 〈/b 〉 〈br 〉 〈hr 〉 “ ) ;<BR>}<BR>}<BR>〈/script 〉<BR>〈html 〉<BR>〈body 〉<BR>在 C#页面中读取指定Cookie值〈br 〉<BR>〈form runat = “server“ 〉<BR>请输入要读取的Cookie名称：〈asp:textbox id = “NameField“ runat = “server“ /〉<BR>〈asp:button text = “读取cookie“ onclick = “ReadClicked“ runat = “server“ /〉<BR>〈/form 〉<BR>〈/body 〉<BR>〈/html 〉</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>四、总结：</FONT></P>
<P><FONT style="BACKGROUND-COLOR: #000000" color=#000000>至此我们已经介绍了用 C#进行Cookie编程的大部分内容。其实Cookie在互联网上有着比较大的作用。譬如它可让WEB站点跟踪特定访问者的访问次数、最后访问时间和访问者进入站点的路径等；还可告诉在线广告商广告被点击的次数，从而可以更精确的投放广告；它可让用户在不键入密码和用户名的情况下进入曾经浏览过的一些站点；最为重要的是它可帮助站点统计用户资料以实现个性化服务等等。掌握了 C#的Cookie编程，就可以在程序中充分利用Cookie来实现上面的这些功能了。不信你试一试。&nbsp; <BR></FONT></P><img src ="http://www.blogjava.net/songfei/aggbug/19770.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-11-14 21:36 <a href="http://www.blogjava.net/songfei/articles/19770.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ASP.NET中利用cookies保持客户端信息</title><link>http://www.blogjava.net/songfei/articles/19764.html</link><dc:creator>天外飞仙</dc:creator><author>天外飞仙</author><pubDate>Mon, 14 Nov 2005 12:54:00 GMT</pubDate><guid>http://www.blogjava.net/songfei/articles/19764.html</guid><wfw:comment>http://www.blogjava.net/songfei/comments/19764.html</wfw:comment><comments>http://www.blogjava.net/songfei/articles/19764.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/songfei/comments/commentRss/19764.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/songfei/services/trackbacks/19764.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=16 width="100%" border=0>
<TBODY>
<TR>
<TD height=118><BR><BR><SPAN class=article-info>日期：2004-2-16 22:16:56<BR>出处：统一教学网 <BR>作者：-</SPAN></TD></TR>
<TR>
<TD class=content>
<TABLE cellSpacing=0 cellPadding=0 align=left border=0>
<TBODY>
<TR>
<TD>
<SCRIPT type=text/javascript><!--
google_ad_client = "pub-4911831409822175";
google_ad_width = 300;
google_ad_height = 250;
google_ad_format = "300x250_as";
google_ad_channel ="";
google_color_border = "CCCCCC";
google_color_bg = "FFFFFF";
google_color_link = "000000";
google_color_url = "666666";
google_color_text = "333333";
//--></SCRIPT>

<SCRIPT src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript>
</SCRIPT>
</TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 align=right border=0>
<TBODY>
<TR>
<TD>
<SCRIPT language=JavaScript src="/ad/ad.js"></SCRIPT>
<IFRAME name=mq marginWidth=0 marginHeight=0 src="../../ad.html" frameBorder=no width=0 scrolling=no height=0></IFRAME></TD></TR></TBODY></TABLE>
<P>我当前所吃的东东都固定为食物，所以一点也不惊讶，这一周的主题为cookies。</P>
<P><BR>Cookies用于存储特定用户信息，它提供了Web程序中一种有用的方式。多年以来，JavaScript开发人员已经进行了有关cookie的大量工作。同样，ASP.NET通过System.Web空间名称也提供了cookie的访问。虽然你不应该使用cookie来存储一些敏感性的数据，但是，它们是处理锁细数据的一个极好的选择，比如颜色参数选择或者最后一次访问日期。</P>
<P>传递cookies<BR>cookie是存储在客户端计算机的一个小文件。如果你是一个Windows用户，可以在用户路径中查看Cookies路径，即为Documents And Settings路径。这一路径包含这一文件名称的文本文件：</P>
<P>username @ Web site domain that created the cookie </P>
<P>(用户名称@建立cookie的站点域名)</P>
<P>.NET System.Web空间名称包含三个类，你可以使用它们来处理客户端的Cookies：</P>
<P>HttpCookie：提供一个建立和操作独立HTTP cookies的安全类型的方式。</P>
<P>HttpResponse：Cookies属性允许客户端cookies被操作。</P>
<P>HttpRequest：Cookies属性允许访问客户端操作的cookies。</P>
<P>HttpResponse和HttpRequest对象的Cookies属性将返回一个HttpCookieCollection对象，它包含着，将单独的cookies添加到集合(collection)中，以及从集合(collection)获得一个单独的cookies。</P>
<P>HttpCookie类<BR>HttpCookie类针对于客户存储之用而建立的单独cookies。一旦HttpCookie对象被建立，你可以涮砑拥紿ttpResponse对象的Cookies属性中。同样的，你可以通过HttpRequest对象访问现有的cookies。HttpCookie类包含以下的公有属性：</P>
<P>Domain(域名)：获得或设置与cookie有关的域名，可用于限制特定区域的cookie访问。</P>
<P>Expires(期限)：获得或设置cookie的终止日期和时间，你可以将其设置为一个过去的日期以自动终止或者删除cookie。</P>
<P>Names(名称)：获得或设置cookie名称。</P>
<P>Path(路径)：获得或设置cookie的虚拟路径。这一属性允许你限制cookie范围，也就是说，访问cookie只能限制于一个特定的文件夹或者路径。设置这一属性限制为只能访问特定路径和该路径下的所有文件。</P>
<P>Secure(安全)：发信号以表示是否使用Secure Sockets Layer (SSL)来发送cookie值。</P>
<P>Value(值)：获得或设置一个单独的cookie值。</P>
<P>Values(信息)：返回包含在cookie中的key/value的一个集合。</P>
<P>虽然这些还不是一个最详尽的列表，但它提供了处理cookies所需要的东西。对于这些属性的使用，以下VB.NET范例给予最好的理解：</P>
<P>Dim testCookie As New HttpCookie("LastVisited")</P>
<P>testCookie.Value = DateTime.Now.ToString</P>
<P>testCookie.Expires = DateTime.Now.AddDays(7)</P>
<P>testCookie.Domain = "builder.com"</P>
<P>Response.Cookies.Add(testCookie) </P>
<P>这一代码段建立了一个名为LastVisited的新的cookie，并赋予当前日期和时间的值。同样的，cookie终止期限设置为一个星期，相关的范围为populated。一旦建立对象，通过Response.Cookies对象的Add方法就可以将对象添加到客户端的cookies集合。HttpCookie构造函数中的方法有两种：</P>
<P>HttpCookie objectName = New HttpCookie("cookieName") </P>
<P>HttpCookie objectName = New HttpCookie("cookieName", "cookieValue") </P>
<P>同样，Response对象包含一个SetCookie方法，这一方法可以接受一个HttpCookie对象。</P>
<P>我的cookie在哪里？<BR>一旦cookies被保存在客户端，有多种不同的方法以提供你访问它们。如果你知道cookie名称，可以使用HttpResponse对象很容易地访问它的值。以下VB.NET行显示了与cookie有关的值：</P>
<P><BR>&nbsp;</P>
<P>Response.Write(Request.Cookies("LastVisitied").Value) </P>
<P>&nbsp;</P>
<P>除此之外，可以通过一个HttpCookieCollection对象访问cookies的完整列表。这就使得cookie列表可以用一个for循环来访问。以下C#代码说明了这样的例子：</P>
<P>HttpCookieCollection cookies;</P>
<P>HttpCookie oneCookie;</P>
<P>cookies = Request.Cookies;</P>
<P>string[] cookieArray = cookies.AllKeys;</P>
<P>for (int i=0; I &lt; cookieArray.Length; i++) {</P>
<P>oneCookie = cookies[cookieArray[i]];</P>
<P>Response.Write(oneCookie.Name + " - " + oneCookie.Value);</P>
<P>} </P>
<P>&nbsp;</P>
<P>VB.NET中相应的代码如下：</P>
<P>&nbsp;</P>
<P>Dim i As Integer</P>
<P>Dim oneCookie As HttpCookie</P>
<P>For i = 0 To Request.Cookies.Count - 1</P>
<P>oneCookie = Request.Cookies(i)</P>
<P>Response.Write(oneCookie.Name + " - " + oneCookie.Value)</P>
<P>Next I </P>
<P>稳定也是一个观点<BR>cookie文件存放在客户端机器，所以你的用户可以任意删除或更改。此外，用户还可以使cookies无效化。基于此原因，请记住不要依赖cookie数据。你应该将重要的信息保存在服务器──特别是一个数据库中。</P>
<P>在一个cookie中存储关键信息被认为是一种低级的程序设计，因为这些信息很容易被泄露，原因是这些信息位于客户机器的一个文件中。在这一点，一种方法就是使用SSL，这是一种可以避免敏感信息的更好方法。</P>
<P>&nbsp;</P>
<P>我可以使用cookies吗？<BR>用户可以在自己的浏览器上无效化cookie支持。你可以在自己的代码中访问这些设置以决定是否支持cookies。Request对象满足了这一想法，以下VB.NET代码显示了这一过程：</P>
<P>&nbsp;</P>
<P>If Request.Browser.Cookies = True Then</P>
<P>' 使用cookies</P>
<P>Else</P>
<P>'没有cookie支持</P>
<P>End If </P>
<P>&nbsp;</P>
<P>可以联合代码来使用cookie值。以下C#代码段对cookie支持进行了测试，并相应地将结果显示在一个文本框：</P>
<P>if (Request.Browser.Cookies == true)</P>
<P>{</P>
<P>if (Request.Cookies["LastVisited1"] == null)</P>
<P>{</P>
<P>HttpCookie newCookie = new HttpCookie("LastVisited1",DateTime.Now.ToString());</P>
<P>newCookie.Expires = DateTime.Now.AddYears(1);</P>
<P>Response.Cookies.Add(newCookie);</P>
<P>this.txtName.Text = "Is this your first time?";</P>
<P>} else {</P>
<P>this.txtName.Text = "We haven't seen you since " +</P>
<P>&nbsp;Request.Cookies["LastVisited1"].Value;</P>
<P>}&nbsp; } </P>
<P>&nbsp;</P>
<P>你可以将这一代码段添加到ASP.NET页中的Page_Load事件。</P>
<P>保存数据的另一方式<BR>ASP.NET提供了保存特定用户数据的多种方法。其中一个老方法就是cookies。对于敏感数据，虽然cookies不是最好的方法，但它是诸如颜色参数选择、最后一次访问日期等亲和力选项(benign items)的最佳选择。虽然这些敏感数据重要，但当用户的计算机崩溃时数据丢失，这也不是世界的末日。</P></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/songfei/aggbug/19764.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/songfei/" target="_blank">天外飞仙</a> 2005-11-14 20:54 <a href="http://www.blogjava.net/songfei/articles/19764.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>