守望者

-----在路上,在桌前,在月下,在梦中……。你守望着什么?是执着的梦想、甜蜜的爱情,还是……

导航

<2012年5月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

公告

天涯共此一杯酒,
相逢莫问皆故人。

统计

文章分类

档案

随笔分类

相册

多媒体

登录

2004年7月23日 #

多窗口页面(Frames)

 

基本语法

<frameset> ... </frameset>
<frame src="url">
<noframes> ... </noframes>

在 <noframes> 标记后的文字将只出现在不支持 FRAMES 的浏览器中。

        <HTML>
        <HEAD>
        </HEAD>
        <FRAMESET>
             <FRAME SRC="url">
             <NOFRAMES> ... </NOFRAMES>
        </FRAMESET>
        </HTML>

各窗口的尺寸设置

<frameset cols=#>

纵向排列多个窗口:
<frameset cols=30%,20%,50%>
<frame src="A.html">
<frame src="B.html">
<frame src="C.html">
</frameset>

<frameset rows=#>
横向排列多个窗口:
<frameset rows=25%,25%,50%>
<frame src="A.html">
<frame src="B.html">
<frame src="C.html">
</frameset>

COLS & ROWS

纵横排列多个窗口:
<frameset cols=20%,*>
<frame src="A.html">
     <frameset rows=40%,*>
     <frame src="B.html">
     <frame src="C.html">
     </frameset>
</frameset>

不允许各窗口改变大小 <frame noresize>

缺省设置是允许各窗口改变大小的。

各窗口间相互操作(Frame Target)

窗口标识(Frame Name)
<frame name=#>
<a href=url target=#>

<frameset cols=50%,50%>
<frame src="A.html">
<frame src="B.html" name="HELLO">
</frameset>
特殊的 4 类操作(很有用喔)
<a href=url target=_blank> 新窗口
<a href=url target=_self> 本窗口
<a href=url target=_parent> 父窗口
<a href=url target=_top> 整个浏览器窗口

 Frame 的外观(Appearance)

各窗口边框的设置 <frame frameborder=#> #=yes, no / 1, 0

<frameset rows=30%,*>
<frame src="Acol.html" frameborder=1>
<frameset cols=30%,*>
     <frame src="Bcol.html" frameborder=0>
     <frame src="Ccol.html" frameborder=0>
</frameset>
</frameset>

A
B C

各窗口间空白区域的设置
<frameset framespacing=#> #=空白区域的大小

<frameset rows=30%,* framespacing=100>
<frame src="Acol.html">
<frameset cols=30%,*>
     <frame src="Bcol.html">
     <frame src="Ccol.html">
</frameset>
</frameset>
A
B C

边框色彩 <frameset bordercolor=#>

#=rrggbb 16 进制 RGB 数码, 或者是下列预定义色彩名称:
Black, Olive, Teal, Red, Blue, Maroon, Navy, Gray, Lime,
Fuchsia, White, Green, Purple, Silver, Yellow, Aqua
<frameset rows=30%,* bordercolor=red>
<frame src="Acol.html">
<frameset cols=30%,*>
     <frame src="Bcol.html">
     <frame src="Ccol.html">
</frameset>
</frameset>
A
B C

页面空白(Margin) <frame marginwidth=# marginheight=#>

<frameset cols=50%,50%>
<frame src="A.html">
<frame src="A.html" 
    marginwidth=50 
    marginheight=50>
</frameset>
AAAA AA
AA

卷滚条设置 <frame scrolling=#> #=yes, no, auto

#=缺省值是 auto。

 

浮动窗口(Floating Frame)

<iframe src=# name=##> ... </iframe>
#=初始页面的 URL
##=窗口标识(Frame Name)(之后可对此标识进行各窗口间相互操作)
... = 此处文字将只出现在不支持 FRAMES 的浏览器中。

<center>
<iframe src="A.html" name="window">
   Here is a Floating Frame
</iframe>
<br><br>
<a href="A.html" target="window">Load A</A><BR>
<a href="B.html" target="window">Load B</A><BR>
<a href="Ccol.html" target="window">Load C</A><BR>
</center>

17:09 | 评论 (0)

如何实现文本框焦点自动跳转及通过回车键提交表单

该文章讲的是在ASP.NET登录页面中如何实现文本框焦点自动跳转及通过回车键提交表单。
所需的Javascript代码:
<script language="JavaScript">

NS4 = (document.layers) ? true : false;

function checkEnter(event,element)

{    

    var code = 0;

    if (NS4)

        code = event.which;

    else

        code = event.keyCode;

    if (code==13)

     {

         if(element.name=='tbUserName')//tbUserName-用户名文本框的Name

         {

              document.frmLogin.tbPassword.focus();//frmLogin-表单名称,tbPassword-密码文本杠框的Name

         }

         if(element.name=='tbPassword')

         {

              //document.frmLogin.submit();用这种方式提交,Asp.net页面会闪一下,但实际并未提交

              //用下面的代码才能提交,我是从asp.net生成的页面中查看源文件然后复制出来的

              if (typeof(Page_ClientValidate) != 'function' ||  Page_ClientValidate()) __doPostBack('lblLogin','');

         }

     }

}

 

</script>

我将这些代码放在了一个LoginScript.js文件中,然后在Login.cs文件中添加如下代码就实现这样的功能:

tbUserName.Attributes.Add("onKeyPress","checkEnter(event,this)");

tbPassword.Attributes.Add("onKeyPress","checkEnter(event,this)");

System.IO.StreamReader sr=new System.IO.StreamReader(MapPath("Script")+"\\LoginScript.js");

this.RegisterClientScriptBlock("LoginScript",sr.ReadToEnd());

sr.Close();

16:47 | 评论 (0)

2004年6月25日 #

怎么给动态产生的checkbox设置事件?

在类外事件定义:public ......
在类外事件定义:public delegate void  Handler(object sender,EventArgs e,int i);
在类中事件说明:public event Handler Newevent;

在类中写事件方法:
      private void test_event(object sender,EventArgs e,int i)
      {
          Button control = ( Button ) sender ;
         MessageBox.Show ("发生的事件在按钮:"+control.Text+"\n传入数据是:"+i+"\n"+e.ToString());
         
      }

在控件生成时候添加事件:this.Newevent+=new Handler(test_event);   

调用事件:private void button3_Click(object sender, System.EventArgs e)
      {
                        

         try
         {
            int i=5500;
            Newevent(sender,e,i);//调用事件处理 
         }
         catch(System.Exception ee)
         {
            MessageBox.Show(ee.Message.ToString(),"错误信息");
         }
      }

9:39 | 评论 (1)

[转载]DataGrid中创建复杂表头方法

有时候经常在DataGrid有复杂表头的显示要求但DataGrid本身并不提供这方面的解决方法,现在对这个问题做个讨论
1)添加一个table
创建跨多列、多行表头的DataGrid[http://www.csdn.net/Develop/Read_Article.asp?Id=18971]
这是CSDN中net_lover的一个文章可以
个人观点:可以解决一些问题,但并不能冶本,只是冶标而已.

2)在Pager中添加
这也是CSDN的一个文章,具体方法是在Pager创建时将Pager列去掉而和Header一起形成两行表头(注Pager会在Header前先建立)
但要添加三行以上时...可能会有点麻烦,对二行来说是最好的选择了

3)我现在介绍另一种利用JavaScript来形成表头的方法.
[个人感觉还好..能形成复杂的表头]

其它就不多说了就把这个代码写一下,希望对大家有帮助

         SqlConnection Cn=new 

SqlConnection(System.Configuration.ConfigurationSettings.AppSettings.Get("Cnstr"));
         SqlDataAdapter SqlDa=new SqlDataAdapter("SELECT * FROM jobs",Cn);
         DataSet ds=new DataSet();
         SqlDa.Fill(ds);
         this.DataGrid1.DataSource=ds;
         this.DataGrid1.DataBind();


         string javaScript;
         javaScript="<script language='javascript'>";
      

         javaScript+=@"   
         function addrow()
         {
             var oRow=document.all(obs).insertRow(0);
             var oCell0=oRow.insertCell();
             with(oCell0)
             {
                innerText='hello';
             
             }
            var oCell1=oRow.insertCell();
            with(oCell1)
            {
               innerText='Kitty';
            }
            var oCell2=oRow.insertCell()
            with(oCell2)
            {
               innerText='Lvl';
               colSpan='2';
            }
            
         }
         addrow();
         ";
         javaScript=javaScript.Replace("obs","'" + this.DataGrid1.ClientID +"'");
         javaScript+="<";
         javaScript+=@"/";
         javaScript+="script>";

         Page.RegisterStartupScript("ss",javaScript);


以上代码是对pubs数据库的操作
总体来说是用insertRow()和insertCell()来进行的..
然后用with(oCell)来进行里面的样式控制..

9:38 | 评论 (2)

上传大文件

在SDK中找到如下一段话,共享一下:
------------------------------------------------------------------------
上载大文件时,可使用 <httpRuntime> 元素的 maxRequestLength 属性来增加文件大小的最大允许值。当文件超出指定的大小时,浏览器中会产生 DNS 错误。上载大文件时,还可能会收到以下错误信息:
aspnet_wp.exe (PID: 1520) 被回收,因为内存消耗超过了 460 MB(可用 RAM 的百分之 60)。
如果遇到此错误信息,请增加应用程序的 Web.config 文件的 <processModel> 元素中 memoryLimit 属性的值。
------------------------------------------------------------------------

不过注意,上面这句话中有错:“请增加应用程序的 Web.config 文件的 <processModel> 元素中 memoryLimit 属性的值。”
你无法在Web.config 文件中使用<processModel> ,因为系统提示你不能进行覆盖machine.config中的此小节的配置,所以你只能修改machine.config中的配置了

9:35 | 评论 (0)

[转帖]ADO.NET使用经验集[1]

ADO.NET使用经验集
 作者:
 

  介绍 

  本文为ADO.NET应用程序提供实现最佳性能、可伸缩性和功能的解决方案;它介绍了ADO.NET中可用对象的使用,并为优化ADO.NET应用程序的设计提供了一些建议。 

  本文包括: 

  l .NET框架组件中包含的数据提供者信息 

  l DataSet 与DataReader的比较,这些对象最佳使用说明 

  l 说明怎样使用DataSet、Commands和Connections 

  l 与XML集成的信息 

  l 一般的技巧 


.NET框架组件数据提供程序


  .NET框架组件中的数据提供程序是应用程序与数据源之间的一座桥梁。它允许你从数据源返回查询的结果,在数据源上执行命令,把数据集中的改变提交到数据源。本文包含了怎样选择最适合需求的.NET框架组件数据提供程序。 

  使用哪种.NET框架组件数据提供程序 

  为了使应用程序获得最佳的性能,需要使用最适合数据源的.NET框架组件数据提供程序。 

  连接到SQL Server 7.0及以上版本 

  当连接到SQL Server 7.0及以上版本时,为了获得最佳性能应该使用SQL Server .NET 数据提供程序。SQL Server .NET数据提供程序设计为直接访问SQL Server,没有其它附加的技术层。下图(图1)说明了访问SQL Server 7.0及以上版本的多种技术之间的差别。 

 

  图1.访问SQL Server 7.0及以上版本的连接方法 

  连接到ODBC数据源 

  名字空间中的ODBC .NET数据提供程序的结构与SQL Server和OLE DB的.NET数据提供程序相同。ODBC .NET数据提供程序使用"ODBC"前缀和标准的ODBC连接字符串。 

  注意:ODBC .NET数据提供程序包含在.NET框架组件1.1以上版本,包含ODBC .NET数据提供程序的名字空间是System.Data.Odbc。 


使用DataReader、DataSet、DataAdapter和DataView


  ADO.NET提供两个对象用于检索关系型数据并把它存储在内存中,分别是DataSet和DataReader。DataSet提供内存中关系数据的表现--包括表和次序、约束等表间的关系的完整数据集合。DataReader提供快速、只向前、只读的来自数据库的数据流。 

  使用DataSet时,一般使用DataAdapter(也可能是CommandBuilder)与数据源交互,用DataView对DataSet中的数据进行排序和过滤。DataSet可以被继承来建立强化类型的DataSet,用于暴露表、行、列作为强化类型对象属性。 

  下面的内容包含什么时候使用DataSet或DataReader,以及怎样优化访问它们所包含的数据,也包括怎样优化DataAdapter和DataView的使用(也包括CommandBuilder)。 

  DataSet与DataReader的对比 

  在设计应用程序时,决定使用DataSet还是DataReader需要考虑应用程序需要的功能。 

  使用DataSet是为了实现应用程序的下述功能: 

  l 操作结果中的多个分离的表。 

  l 操作来自多个源(例如来自多个数据库、XML文件和电子表格的混合数据)的数据。 

  l 在层之间交换数据或使用XML Web服务。与DataReader 不同,DataSet能被传递到远程客户端。 

  l 通过缓冲重复使用相同的行集合以提高性能(例如排序、搜索或过滤数据)。 

  l 每行执行大量的处理。在使用DataReader返回的行上进行扩展处理将使连接存在的时间比必要的更长,从而降低效率。 

  l 使用XML操作(例如XSLT转换和Xpath查询)维护数据。 

  在应用程序需要以下功能时使用DataReader: 

  l 不需要缓冲数据。 

  l 正在处理的结果集太大而不能全部放入内存中。 

  l 需要迅速一次性访问数据,采用只向前的只读的方式。 

  注意:当填充DataSet的时候,DataAdapter使用DataReader。因此使用DataAdapter代替DataSet获得的性能是节约了DataSet消耗的内存和组装DataSet所需要的周期。这种性能的提高大部分是有名无实的,因此你应该根据需要的功能为基础来做设计决定。 

  使用强类型DataSet的好处 

  使用DataSet的另一个好处是它能被继承用于建立强类型的DataSet。强类型DataSet的好处包括设计时的检查和强类型DataSet 的Visual Studio .NET语句填充。当你为DataSet固定了大纲或关系结构时,就能建立强类型DataSet,把行和列作为对象的属性而不是项的集合。例如,作为暴露顾客表的某一行的列名的代替,你可以暴露Customer对象的 Name属性。强类型的DataSet衍生自DataSet类,因此不会牺牲DataSet的任何功能,也就是说,强类型的DataSet也可以是远程的,并作为数据绑定控件(例如DataGrid)的数据源提供。如果不知道大纲,也能通过使用通常的DataSet获得好处,但是丧失了强类型DataSet的附加特性。 

  在强类型DataSet中处理空值 

  使用强类型DataSet时,你能给DataSet 的XML大纲定义语言(XSD)作注解以确保强类型DataSet正确的处理空(Null)的引用。空值(nullValue)注释使你能用String.Empty这个特定值代替DBNull、保持了空引用、或者产生一个异常。选择其中的哪个依赖于应用程序的内容,默认情况下遇到空引用将产生一个异常。 

  刷新DataSet中的数据 

  如果你希望使用更新后的值从服务器刷新数据集中的值,使用DataAdapter.Fill。如果主键定义在数据表上,DataAdapter.Fill基于主键匹配新行,并把服务器的数据改成已存在的行。被刷新行的RowState设置为Unchanged,即使在刷新前它被修改过。注意如果给数据表定义了主键,DataAdapter.Fill添加新行可能重复主键值。 

  如果希望用服务器的当前值刷新一个表,并且保持表中行的改变,你必须首选使用DataAdapter.Fill组合它,填充一个新的数据表,接着将该数据表合并(Merge)进一个数据集,并把preserveChanges值设为true。 

  在DataSet中搜索数据 

  在一个数据集中查询符合特定条件的行时,使用基于索引(index-based)的查看表将提高性能。给数据表指定主键(PrimaryKey)值时,就建立了一个索引。当为数据表建立数据视图(DataView)时也建立了索引。下面是一些使用基于索引查看的技巧: 

  如果查询是在数据表的主键列上进行的,使用DataTable.Rows.Find代替DataTable.Select。 

  查询非主键列,可以使用数据视图来提高多个数据查询的速度。当给数据视图添加排序时,将建立搜索时使用的索引。数据视图暴露了查询下层数据表的Find和FindRows方法。 

  如果你不是查询表的排序视图,也可以通过为数据表建立数据视图获得基于索引的查看表的好处。注意如果你执行数据上的多个查询这是唯一的好处。如果你只执行单个查询,需要建立索引的过程将因为使用索引而降低了性能。 

  数据视图(DataView)结构 

  当数据视图建立后,并且当Sort、RowFilter或RowStateFilter或者属性被修改时,数据视图为下层数据表中的数据建立索引。当建立数据视图对象时,使用把Sort、RowFilter和RowStateFilter值作为参数的数据视图构造函数。结果是建立了一次索引。建立"空"数据视图,然后设置Sort、RowFilter和RowStateFilter属性将导致至少两次建立索引。 

  分页 

  ADO.NET给了你从数据源返回什么数据的明显控制,也提供了在数据集中存储了多少数据的控制。在设计应用程序时可以考虑以下技巧: 

  l 避免使用DataAdapter.Fill,它使用了startRecord和maxRecords值。使用这种方式填充数据集时,数据集只填充由maxRecords参数指定的记录个数(从参数startRecord指定的记录开始),而不管返回的整个查询。这导致读取过时的"不想要的"记录,同时使用了不必要的服务器资源来返回补充记录。 

  l 用于在某个时候只返回一页记录的技术之一是建立一个SQL语句,该语句包含一个WHERE和ORDER BY子句,并有TOP判定。这种技术依赖于识别每个唯一行的方法。当导航到下一页的记录时,修改WHERE子句使它包含所有唯一标识比当前页标识大的记录;当导航到前面一页时,修改WHERE子句使它包含所有唯一标识比当前页标识小的记录。对于两种查询都只返回记录的TOP页的记录。当导航到前面一页时需要对记录进行降序排列,这将返回查询的末尾页(如果需要可以在显示前对记录进行重新排序)。 

  l 另一种技术是建立一个SQL语句包含TOP判定和嵌入的SELECT语句。这种技术不是基于唯一的识别每行的方法。使用这种技术的第一步是把页面的大小与想得到的页面数量相乘。接着把该数值传递给SQL查询的TOP判定,并按升序排序。接着把这个查询嵌入另一个查询,该查询从嵌入的查询结果中选择TOP页面大小,按降序排列。本质上返回的是嵌入的查询的末尾页面。例如,为了返回页面大小是10的查询结果的第三页,使用下面的命令: 

SELECT TOP 10 * FROM
  (SELECT TOP 30 * FROM Customers ORDER BY Id ASC) AS Table1
ORDER BY Id DESC
 


  l 如果数据不是经常改变,能通过本地维护数据集里面的记录缓存来提高性能。例如,你能在本地数据集中存储10页数据,只在用户导航超出第一页或最后一页时才查询数据源检索新的数据。 

  使用大纲(Schema)填充数据集 

  当用数据填充数据集时,DataAdapter.Fill方法使用数据集的已存在的大纲并把它与Select命令(SelectCommand)返回的数据进行组合。如果数据集中没有与被填充的表匹配的表的名字,Fill方法将建立一张表。默认情况下,Fill只定义列和列的类型。 

  你能通过设置数据适配器的MissingSchemaAction属性来重载Fill的默认的行为。例如,要使Fill建立的表包含主键信息、唯一约束、列属性、是否允许空值、列的最大长度、只读列、自动增加列等等,只需要指定DataAdapter.MissingSchemaAction为MissingSchemaAction.AddWithKey。作为选择,你能在调用DataAdapter.Fill前调用DataAdapter.FillSchema来确保数据集被填充时大纲已经准备好了。 

  调用FillSchema将再次访问服务器并检索附加的大纲信息。为了提高性能,最好指定数据集的大纲,或者在调用Fill前设置数据适配器的MissingSchemaAction。 

  使用命令构造器(CommandBuilder)的经验 

  命令构造器根据数据适配器的SelectCommand属性自动生成数据适配器的InsertCommand、UpdateCommand和DeleteCommand属性(假若SelectCommand执行单个表上的选择(SELECT))。 

  l 命令构造器的使用应该限制在设计时或者ad-hoc情况下。需要的生成数据适配器命令属性的过程妨碍了性能。如果你预先知道INSERT/UPDATE/DELETE语句的内容,应该显式地设置它们。好的设计技巧是为INSERT/UPDATE/DELETE命令建立存储过程并明确地配置数据适配器命令属性来使用它们。 

  l 命令构造器使用数据适配器的SelectCommand属性来决定其它命令属性的值。如果数据适配器的SelectCommand自身改变了,一定要调用RefreshSchema来更新命令属性。 

  l 如果命令属性是空的(默认情况下命令属性是空的),命令构造器只为数据适配器命令属性生成一个命令。如果你明确地设置一个命令属性,命令构造器不会覆盖它。如果你希望命令构造器为一个已经设置了的命令属性生成一个命令,要把命令属性设置为空。 

  批处理SQL语句 

  很多数据库支持在一个命令执行中组合、批处理多个命令执行。例如,SQL Server允许你使用分号分隔命令。把多个命令组合成为一个减少了对服务器的访问次数,可以提高应用程序的性能。例如,你能在本地应用程序中存储所有的删除,并在数据源发布一个批处理命令调用来删除它们。 

  尽管它提高了性能,但是也增加了应用程序管理数据集里面数据更新的复杂性。为了保持简单性,你也许会为数据集中的每个数据表建立一个数据适配器。 

  使用多个表填充数据集   

  如果使用批处理SQL语句检索多个表并填充一个数据集,第一张表的名字使用Fill方法指定的表名,后面的表的名字是Fill方法指定的名字加上一个数字,从1开始逐渐增加。例如,如果运行下面的代码: 

'Visual Basic
Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers;
   SELECT * FROM Orders;", myConnection)
Dim ds As DataSet = New DataSet()
da.Fill(ds, "Customers")

//C#
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers; 
  SELECT * FROM Orders;", myConnection);
DataSet ds = new DataSet();
da.Fill(ds, "Customers");
 


  从Customers表中得到的数据放在叫"Customers"的数据表中,从Orders表中得到的数据放在"Customers1"数据表中。 

  你可以在数据表被填充后修改"Customers1"表的属性为"Orders"。但是接下来的填充的结果是"Customers"表被重新填充,但是"Orders"表被略过了并且建立了另一个"Customers1"表。为了避免这种情况,建立一个把"Customers1"映射到"Orders"的DataTableMapping,并且为其它的表建立映射。例如: 

'Visual Basic
Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers; 
  SELECT * FROM Orders;", myConnection)
da.TableMappings.Add("Customers1", "Orders")
Dim ds As DataSet = New DataSet()
da.Fill(ds, "Customers")

//C#
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers; 
  SELECT * FROM Orders;", myConnection);
da.TableMappings.Add("Customers1", "Orders");
DataSet ds = new DataSet();
da.Fill(ds, "Customers");
 


  使用DataReader 

  下面是使用DataReader提高性能的一些技巧: 

  l 在访问任何与命令(Command)相关的输出参数前DataReader必须关闭。 

  l 在读完数据后就关闭DataReader。如果你正在使用的连接只返回该DataReader,在关闭DataReader后立即关闭连接。 

  l 另一种明确地关闭连接的方法是给ExecuteReader方法传递CommandBehavior.CloseConnection以确保当DataReader关闭时相关的连接关闭了。如果你从某个方法返回DataReader,并且没有办法控制DataReader或者相关的连接关闭的情况下特别有用。 

  l DataReader不能在层之间远程访问。DataReader是设计用于连接数据访问的。 

  l 使用类型化的存取程序(例如GetString、GetInt32等等)来访问列数据。这节省了将GetValue返回的对象作为特定类型的必要的处理。 

  l 在某一时刻只有一个DataReader能够打开。。在ADO中,如果你打开一个连接并请求两个使用只向前的只读游标的记录集,ADO隐性地为游标的生命周期的数据存储打开第二个不在连接池中的连接,接着隐性地关闭它。在ADO.NET中,如果你想在同一个数据存储上同时打开两个DataReader,你必须明确地建立两个连接,每个DataReader一个。通过这种方法ADO.NET给了你对连接池使用的更多控制。 

  l 默认情况下,DataReader在每个Read方法中把整个行载入内存中。这允许你随机访问当前行的任意列。如果随机访问是不必要的,为了提高性能,把CommandBehavior.SequentialAccess传递给ExecuteReader调用。这改变了DataReader的默认行为,只在需要时才把数据载入内存。注意CommandBehavior.SequentialAccess要求你按次序访问返回的列。也就是,一旦你读过了返回的某个列,就不能再次读取它的值了。 

  l 如果你结束了从DataReader中读取数据,但是仍然有大量的未读取的结果等待,那么调用Command的Cancel比调用DataReader 的Close好。调用DataReader 的Close引起它检索等待的结果并且先清空流后关闭游标。调用Command的 Cancel删除服务器上的结果,因此当DataReader关闭时,它不需要再读取结果。如果你从Command返回输出参数,则调用Cancel删除它们。如果你要读取任何输出参数,不要调用Command 的Cancel;最后调用DataReader的 Close。 

  二进制大对象(BLOB) 

  当使用DataReader检索二进制大对象时,必须给ExecuteReader方法调用传递CommandBehavior.SequentialAccess。因为DataReader的默认行为是在每个Read中把整行载入内存中,但是由于BLOB可能很大,结果可能是一个BLOB对象使用大量的内存。SequentialAccess把DataReader的行为设置为只载入必要的数据,接着你能使用GetBytes或者GetChars控制每次载入多少数据。 

  记住使用SequentialAccess时,你不能无序地访问DataReader返回的不同字段。也就是说,如果查询返回三个列,第三个是BLOB,并且你希望访问前两个列的数据,你必须先访问第一个列,接着在访问BLOB数据前访问第二个列。这是因为现在数据是按次序返回的,在DataReader读过它后不能再次访问。 

  使用命令(Command) 

  ADO.NET为命令执行提供了几个不同的方法,同时也为优化命令的执行提供了不同的选择。下面的技巧包括怎样选择最好的命令执行和怎样提供一个被执行命令的性能。 

  使用OleDbCommand的最好经验 

  不同的.NET框架组件数据提供程序之间的命令执行是尽可能标准的。但是,在这些数据提供程序间也有些不同。下面的一些可以调整OLE DB数据提供程序命令执行的技巧: 

  l 与ODBC CALL语法一起使用CommandType.Text来调用存储过程。仅仅使用CommandType.StoredProcedure生成ODBC CALL语法。 

  l 一定要设置OleDbParameter类型、大小(如果可用)、精度和小数位(如果参数是数值型或者十进制型)。注意如果你没有明确地提供参数信息,OleDbCommand使用每一个命令执行重新建立OLE DB参数存取程序。 

  使用SqlCommand的经验 

  使用SqlCommand执行存储过程的技巧:如果你要调用一个存储过程,为SqlCommand的 CommandType属性指定StoredProcedure的CommandType。这样就删除了在命令执行前分析命令的需求,明确地把它标识为存储过程了。 

  Prepare方法的使用 

  Command.Prepare方法能够提高数据源中重复的参数化命令的性能。Prepare指示数据源为多个调用优化特定的命令。为了更高效率地使用Prepare,你必须十分清楚数据源怎样回应Prepare调用。对于类似SQL Server 2000的数据源,命令是隐式优化的,对Prepare的调用是没有必要的,但是对于另一些数据源,例如SQL Server 7.0,Prepare效率更高。 

  明确地指定大纲和元数据 

  在ADO.NET中当用户没有指定元数据信息时,有很多对象推导这些信息。例如: 

  l DataAdapter.Fill方法,如果不存在的话,它在记录集中建立表和列。 

  l CommandBuilder,它为单个的SELECT语句生成数据适配器命令属性。 

  l CommandBuilder.DeriveParameters,它组合Command对象的Parameters集合。 

  但是每次使用这些特性时都会造成效率降低。我们推荐主要在设计时和ad-hoc应用程序中使用这些特性。在可能的情况下,明确地指定大纲和元数据,包括在数据集中定义表和列,定义数据适配器的Command属性,定义Command的Parameter信息。 

  ExecuteScalar和ExecuteNonQuery 

  如果你希望返回单个值,例如Count(*)、 Sum(Price)、或者Avg(Quantity),你可以使用Command.ExecuteScalar。ExecuteScalar返回第一行第一列的值,返回结果集是数量值。ExecuteScalar通过一步完成不仅简化了代码而且提高了性能,而这些工作在使用DataReader时将需要两个处理步骤。 

  当使用不返回行的SQL语句时,类似修改数据(例如插入、更新或者删除)或者只返回输出参数或值,使用ExecuteNonQuery。它通过建立一个空DataReader删除了任何必要的处理。 

  空值的检测   

  如果数据库的某张表的一个列允许空值,你不能使用某个与空值相等的参数来测试它。作为代替,需要编写一个WHERE子句来检测是否列和参数都是空值。下面的SQL语句返回LastName列与赋予@LastName的值相同的行,或者LastName 列和@LastName参数都为空的行: 

SELECT * FROM Customers
WHERE ((LastName = @LastName) OR (LastName IS NULL AND @LastName IS NULL))
 


  把空(Null)作为参数值传递 

  当在命令中把空值作为参数值发送给数据库时,不能使用null(Visual Basic .NET中的Nothing)。作为代替必须使用DBNull.Value。例如: 

'Visual Basic
Dim param As SqlParameter = New SqlParameter("@Name", SqlDbType.NVarChar, 20)
param.Value = DBNull.Value

//C#
SqlParameter param = new SqlParameter("@Name", SqlDbType.NVarChar, 20);
param.Value = DBNull.Value;
 


  执行事务 

  事务模块为ADO.NET作了一些改变。在ADO中,当调用StartTransaction时,该调用后面的任何更新都被认为是该事务的一部分。但是在ADO.NET中,当调用Connection.BeginTransaction时,返回的Transaction对象必须与Command的Transaction属性关联。这种设计使你能在一个连接上执行多重事务。如果Command.Transaction属性没有设置为开始就与连接关联的Transaction,Command失败并出现异常。 

  使用连接 

  高性能的应用程序保持使用最少次数的数据源的连接,也利用了类似连接池的性能增强技术。下面的技巧帮你使用ADO.NET连接数据源时获得更好的性能。 

  连接池 

  SQL Server、OLE DB和.NET框架组件数据提供程序隐性为ODBC提供了连接池。你可以在连接字符串中指定不同的属性控制连接池的行为。 

  用DataAdapter优化连接 

  数据适配器的Fill和Update方法自动地为相关的命令属性打开特定的连接(如果它被关闭的话)。如果Fill或Update方法打开了连接,Fill或Update将在操作完成时关闭它。为了提高性能,只在必要时保持数据库连接打开,同时为多个操作减少打开和关闭连接的次数。 

  我们推荐如果你只执行单个的Fill或Update方法调用,你应该允许Fill或Update隐式打开和关闭连接。如果大量调用Fill或者Update,我们推荐显式打开,进行Fill或Update调用,然后显式关闭连接。 

  此外执行事务时,在开始事务前明确地打开连接,在完成事务后明确地关闭连接。例如: 

'Visual Basic
Public Sub RunSqlTransaction(da As SqlDataAdapter, 
  myConnection As SqlConnection, ds As DataSet)
  myConnection.Open()
  Dim myTrans As SqlTransaction = myConnection.BeginTransaction()
  myCommand.Transaction = myTrans

  Try
    da.Update(ds)
    myTrans.Commit()
    Console.WriteLine("Update successful.")
  Catch e As Exception
    Try
      myTrans.Rollback()
    Catch ex As SqlException
      If Not myTrans.Connection Is Nothing Then
        Console.WriteLine("An exception of type " 
        & ex.GetType().ToString() & _
             " was encountered while attempting to roll back the transaction.")
      End If
    End Try

    Console.WriteLine("An exception of type 
      " & e.GetType().ToString() & " was encountered.")
    Console.WriteLine("Update failed.")
  End Try
  myConnection.Close()
End Sub

//C#
public void RunSqlTransaction(SqlDataAdapter da, 
  SqlConnection myConnection, DataSet ds)
{
  myConnection.Open();
  SqlTransaction myTrans = myConnection.BeginTransaction();
  myCommand.Transaction = myTrans;

  try
  {
    da.Update(ds);
    myCommand.Transaction.Commit();
    Console.WriteLine("Update successful.");
  }
  catch(Exception e)
  {
    try
    {
      myTrans.Rollback();
    }
    catch (SqlException ex)
    {
      if (myTrans.Connection != null)
      {
        Console.WriteLine("An exception of type " + ex.GetType() +
         " was encountered while attempting to roll back the transaction.");
      }
    }

    Console.WriteLine(e.ToString());
    Console.WriteLine("Update failed.");
  }
  myConnection.Close();
}
 


  经常关闭连接(Connection)和DataReader 

  当停止使用Connection或者DataReader对象时,明确地关闭它们。尽管无用单元收集程序最终会清除这些对象,并释放连接和其它可管理资源,但是无用单元收集只在必要时才发生。因此确保昂贵的资源明确地被释放仍然是你的职责。此外,连接如果没有被明确的释放将使它不会返回连接池。例如,如果连接池到达了最大值并且一个连接还有效,该超出范围并且没有被明确关闭的连接才返回到连接池。 

  注意不要在类的Finalize方法中调用Connection、DataReader、或者其它可管理对象的Close或者Dispose方法。在该方法中只释放类直接拥有的不可管理资源。如果类中没有任何不可管理资源,在类定义中不要包含Finalize方法。 

  在C#中使用"Using"语句 

  对C#程序员来说,确保经常关闭Connection和DataReader对象的一个简便方法是使用using语句。Using语句会自动调用留在Using语句范围内的被使用的对象上的Dispose,如下所示: 

//C#
string connString = "Data Source=localhost;
  Integrated Security=SSPI;Initial Catalog=Northwind;";

using (SqlConnection conn = new SqlConnection(connString))
{
  SqlCommand cmd = conn.CreateCommand();
  cmd.CommandText = "SELECT CustomerId, CompanyName FROM Customers";
  
  conn.Open();

  using (SqlDataReader dr = cmd.ExecuteReader())
  {
    while (dr.Read())
      Console.WriteLine("{0}\t{1}", dr.GetString(0), dr.GetString(1));
  }
}
 


  避免访问OleDbConnection.State属性 

  如果连接打开了,OleDbConnection.State使本地OLE DB向DATASOURCEINFO属性集调用IDBProperties.GetProperties来获取DBPROP_CONNECTIONSTATUS属性,这可能引起重新返回数据源。换句话说,检查State属性可能花费很大。因此只在必要时才检查State属性。如果你需要经常检查该属性,你监听OleDbConnection的StateChange事件会使应用程序的性能更好。 

  与XML集成 

  ADO.NET在数据集中提供了广泛的XML集成,并且暴露了一些SQL Server 2000及以上版本所提供的XML功能。你能使用SQLXML 3.0来访问SQL Server 2000及以上版本所提供的XML功能。下面是使用XML和ADO.NET的一些技巧和信息。 

  数据集与XML   

  数据集与XML紧密结合,提供了执行下面操作的能力: 

  l 从XSD大纲载入数据集的大纲或者关系结构。 

  l 从XML载入数据集的内容。 

  l 当没有提供大纲时根据XML文档的内容推断数据集的大纲。 

  l 将数据集的大纲写成XSD大纲。 

  l 将数据集的内容写成XML。 

  l 使用数据集同步访问数据的相关表现、使用XmlDataDocument访问数据的层次表现。 

  注意:你能使用这种同步在数据集的数据上应用XML功能(例如Xpath查询和XSLT变换),或提供所有的关系型视图,或者在保持原XML不变的情况下提供XML文档中的数据的子集。 

  大纲接口 

  当从XML文件中载入数据集时,你能从XSD大纲中载入数据集的大纲,或者在载入数据前预先定义表和列。如果没有XSD大纲,并且你也不知道为XML文件的内容定义怎样的表和列,你能根据XML文档的结构推断大纲。 

  大纲推理作为迁移工具是有用的,但是由于推理过程有下面的限制,它只限于应用程序设计时使用: 

  l 推理大纲引入了附加的处理将降低应用程序的性能。 

  l 所有推理列的类型都是字符串型。 

  l 推理过程是不确定的。这就是说,它基于XML文件而不是预定的大纲。结果是你可能有两个XML文件,它们有相同的预定大纲,却因为它们的内容不同形成了两个完全不同的推理大纲。 

  为XML查询服务的SQL Server 

  如果你为XML查询返回SQL Server 2000结果,你能使用.NET框架组件SQL Server数据提供程序直接用SqlCommand.ExecuteXmlReader方法建立一个XmlReader。 

  SQLXML可管理类 

  在.NET框架组件中有一些类暴露了XML为SQL Server 2000提供的功能。这些类都在Microsoft.Data.SqlXml名字空间中,添加了执行Xpath查询和XML模板文件的能力,也能把XSLT转换为数据。 

避免自动增加(Auto-Increment)值冲突 

  和许多数据源一样,DataSet允许你在添加新行时识别自动增加值的列。在DataSet中使用自动增加列时,由于数据源也有自动增加列,需要避免添加到DataSet中的本地行号与添加到数据源中的行之间的冲突。 

  例如,假设一个表的自动增加主键列是CustomerID。两个新客户信息添加到该表,获得的自动增加CustomerID值分别是1和2。接着只有第二个客户行给数据适配器传递的Update方法,在数据源中新添加的行接受的自动增加CustomerID值是1,与数据集中的2不匹配。当数据适配器用返回值填充表中的第二行时,由于第一个顾客行的CustomerID是1,便出现了错误。 

  为了避免这种情况,我们推荐当使用数据源和数据集中有自动增加列时,数据集中的该列的AutoIncrementStep设为-1,AutoIncrementSeed设为0,同时确保数据源中生成的自动增加标识值从1开始,步长为正。结果是数据集生成负的自动增加值,不会与数据源产生的正自动增加值冲突。另一种选择是使用Guid类型的列带有自动增加列,该算法产生的Guid值在数据集和数据源中永远不同。 

  如果你的自动增加列永远简单的作为唯一值,没有其它的意义,考虑使用Guid代替自动增加列。它们是唯一的,避免了做另外的工作处理自动增加列。 

  查找优化的并发性故障 

  因为DataSet被设计为从数据源断开,所有必须确保当多个客户端更新数据源的数据时应用程序避免冲突。 

  测试优化并发性错误有多种技术。一种是在表的列中包含时间戳。另一种技术是通过使用SQL语句中的WHERE条件检测来验证行中所有的源列值与数据库中的匹配。 

  多线程编程 

  ADO.NET的优化是为了提高性能、吞吐量和可伸缩性。结果是ADO.NET不锁定资源并且只能在单个线程中使用,其中一个例外是DataSet,它对多个阅读程序来说是线程安全安的。但是在写的时候必须锁定DataSet。 

  只在必要的时候使用COM交互操作(Interop)访问ADO 

  ADO.NET被设计成大量应用程序的最佳解决方案。但是,有些应用程序需要只能使用ADO对象。在这些情况下,应用程序能使用COM交互操作访问ADO。注意使用COM交互操作访问ADO的数据将极大的降低性能。设计应用程序时,在实现使用COM交互操作访问ADO这种设计前首选决定ADO.NET是否符合设计需要。   


9:10 | 评论 (0)

[转帖]合并datagrid中内容相同的单元格

有时,我们要把一列中内容相同的单元格合并起来。如下图:
此主题相关图片如下:



合并后的效果图:

此主题相关图片如下:



下面就说说怎么实现的:

Sub SpanGrid()
        Dim i As Integer
        Dim j As Integer
        Dim intSpan As Integer
        Dim strTemp As String
        For i = 0 To DGrid.Items.Count - 1
            intSpan = 1    

'得到第一列(颜色)、第一行单元格中的内容。这里得到是“红色Red”。(datagrid里用了模版列)
            strTemp = CType(DGrid.Items(i).Cells(0).Controls(1), System.Web.UI.WebControls.Label).Text

’循环判断。判断第一列中,和第一行相同的内容。相同做记号,intspan加一
            For j = i + 1 To DGrid.Items.Count - 1
                If String.Compare(strTemp, CType(DGrid.Items(j).Cells(1).Controls(1), System.Web.UI.WebControls.Label).Text) = 0 Then
                    intSpan += 1

'利用datagrid的rowspan属性。(设置控件中单元格跨越的行数为intspan)
                    DGrid.Items(i).Cells(0).RowSpan = intSpan

’把内容相同单元格隐藏
                    DGrid.Items(j).Cells(0).Visible = False
                Else
                    Exit For
                End If
            Next
            i = j - 1
        Next
    End Sub

=======

引用:

 Sub bindgrid()
        '把数据绑定到datagrid        
        ........
        SpanGrid()
End Sub

9:07 | 评论 (0)

用.net操作word

要操作Word,我们就需要Word的对象库文件“MSWORD.OLB”(word 2000为MSWORD9.OLB),通常安装了Office Word后,你就可以在office安装目录的Office10文件夹下面找到这个文件,当我们将这个文件引入到项目后,我们就可以在源码中使用各种操作函数来操作Word。具体做法是打开菜单栏中的项目>添加引用>浏览,在打开的“选择组件”对话框中找到MSWORD.OLB后按确定即可引入此对象库文件,vs.net将会自动将 库文件转化为DLL组件,这样我们只要在源码中创建该组件对象即可达到操作Word的目的!

     在CS代码文件中对命名空间的应用,如:using Word;范例如下:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using Word;

namespace ExamSecure
{
 /// 
 /// ItemToDoc 的摘要说明。
 /// 
 public class ItemToDoc : System.Windows.Forms.Form
 {
  object strFileName;
  Object Nothing;
  Word.ApplicationClass myWordApp=new Word.ApplicationClass();
  Word.Document myWordDoc;
  string strContent="";

  private System.ComponentModel.Container components = null;

  public ItemToDoc()
  {
   //
   // Windows 窗体设计器支持所必需的
   //
   InitializeComponent();

   //
   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
   //
  }
  [STAThread]
  static void Main() 
  {
   System.Windows.Forms.Application.Run(new ItemToDoc());
  }
  /// 
  /// 清理所有正在使用的资源。
  /// 
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if(components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows Form Designer generated code
  /// 
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// 
  private void InitializeComponent()
  {
   // 
   // ItemToDoc
   // 
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
   this.ClientSize = new System.Drawing.Size(292, 273);
   this.Name = "ItemToDoc";
   this.Text = "ItemToDoc";
   this.Load += new System.EventHandler(this.ItemToDoc_Load);

  }
  #endregion

  private void ItemToDoc_Load(object sender, System.EventArgs e)
  {
   WriteFile();
  }
  private void WriteFile()
  {
  
   strFileName=System.Windows.Forms.Application.StartupPath+"\\试题库【"+GetRandomString()+"】.doc";
   Object Nothing=System.Reflection.Missing.Value;
   myWordDoc=myWordApp.Documents.Add(ref Nothing,ref Nothing,ref Nothing,ref Nothing);
   
   #region 将数据库中读取得数据写入到word文件中

   strContent="试题库\n\n\r";
   WriteFile(strContent);
   
   strContent="试题库";
   WriteFile(strContent);


   #endregion 
   
   //将WordDoc文档对象的内容保存为DOC文档
   myWordDoc.SaveAs(ref strFileName,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing,ref Nothing);
   //关闭WordDoc文档对象
   myWordDoc.Close(ref Nothing, ref Nothing, ref Nothing);
   //关闭WordApp组件对象
   myWordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
  }

  /// 
  /// 获取一个随即字符串
  /// 
  /// 
  private string GetRandomString()
  {
   DateTime iNow=DateTime.Now;
   string strDate=iNow.ToString("yyyyMMddHHmmffff");
   
   Random ran=new Random();
   int iRan=Convert.ToInt32(10000*ran.NextDouble());
   string strRan=iRan.ToString();
   //位数不足则补0   
   int iRanlen=strRan.Length;
   for(int i=0;i<4-iRanlen;i++)
   {
    strRan="0"+strRan;
   }
   return strDate+strRan;
  }


  /// 
  /// 将字符串写入到Word文件中
  /// 
  /// 要写入的字符串
  private void WriteFile(string str)
  {
   myWordDoc.Paragraphs.Last.Range.Text=str;
  }


 }
}

9:06 | 评论 (3)

[转帖]在ASP.NET下实现数字和字符相混合的验证码

在ASP.NET下实现数字和字符相混合的验证码 

编程爱好者网站


    经常在论坛里看到有问怎么实现验证码的帖子,其实关于验证码的文章在CSDN,DEV-CLUB等网站上都有很多,但是很多文章只讲诉了如何输出一个随机生成数字或字符的图象,当然了,这个是验证码的核心了,但是对很多ASP.NET的初学者来说,怎么使用它生成的图象又成了一个问题(论坛有不少问这个的),这也是我写本文的一个原因.
    言归正传,关于验证码的原理,我就不多说了,大家可以参见其他文章,文末附有完整的实例代码,里面有详细的注释,你可以跳过解说文字,直接使用
    首先,我要简要说说Session和ViewState的用法,因为后面会用到它
       把数据存储在Session中:Session("key")="test"
       从Session取值:dim testvalue as string=Session("key")
      类似的:
       把数据存储在ViewState中:ViewState("key")="test"
       从ViewState中取值:dim testvalue as string=ViewState("key")
    关于ViewState的更详细的资料,你可以参看MSDN的<<ASP.NET ViewState 初探>>一文
      百闻不如一见,有时代码本身就比任何解说更有表现力,所以在此就不对代码解说太多了,本文实现的验证码需要用到两个文件:
       gif.aspx           该文件用于生成验证码
       ValidateCode.aspx  该文件用来测试验证码(即如何使用)
   下面给出gif.aspx的完整代码:
<%@ import namespace="System"%>
<%@ import namespace="System.io"%>
<%@ import namespace="System.Drawing"%>
<%@ import namespace="System.Drawing.Imaging"%>
<script language="vb" runat="server">
Sub Page_Load(Sender as object,e as eventargs)
    'RndNum是一个自定义函数
    dim VNum as string=RndNum(4)
    Session("VNum")=VNum
    ValidateCode(VNum)
End Sub
'生成图象验证码函数
Sub ValidateCode(VNum)
   Dim Img as System.Drawing.Bitmap
   Dim g as Graphics
   Dim ms as MemoryStream
   dim gheight as integer=Int(Len(VNum)*11.5)
   'gheight为图片宽度,根据字符长度自动更改图片宽度
   img=new BitMap(Gheight,20)
   g=Graphics.FromImage(img)
   g.DrawString(VNum,(New Font("Arial",10)),(New SolidBrush(color.blue)),3,3)'在矩形内绘制字串(字串,字体,画笔颜色,左上x.左上y)
   ms=New MemoryStream()
   img.Save(ms,ImageFormat.Png)
   Response.ClearContent() '需要输出图象信息 要修改HTTP头
   Response.ContentType="image/Png"
   Response.BinaryWrite(ms.ToArray())
   g.Dispose()
   img.Dispose()
   Response.End()
End Sub
  '--------------------------------------------
  '函数名称:RndNum
  '函数参数:VcodeNum--设定返回随机字符串的位数
  '函数功能:产生数字和字符混合的随机字符串
  Function RndNum(VcodeNum)
    dim Vchar as string="0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,W,X,Y,Z"
    dim VcArray() as string=split(Vchar,",") '将字符串生成数组
    dim VNum as string=""
    dim i as byte
    For i=1 to VcodeNum
      Randomize
      VNum=VNum & VcArray(Int(35*Rnd)) '数组一般从0开始读取,所以这里为35*Rnd
    Next
    Return VNum
  End Function
</script>
那么又应该如何使用该文件生成的图象验证码,看这句代码:
<asp:Image id="Image1" runat="server" ImageUrl="gif.aspx" />
这就是用来显示验证码的Image控件,你可以把它放在任何你喜欢的地方,下面的给出详细的使用代码,你把它保存为ValidateCode.aspx,并把它和gif.aspx放在同一目录下,在浏览器中打开ValidateCode.aspx,就可以测试它的效果了:
<script language="vb" Runat="Server">
  Sub Page_Load(Sender as object,e as eventargs)
      dim VNum as string=Session("VNum")
      Session.Abandon()
      ViewState("VNum")=VNum
  End Sub
  '下面的事件代码是用来测试验证码,可以根据需要更改
  Sub btnSubmit_click(sender as object,e as eventargs)
      '判断输入的验证码与所给是否相同
      If txtValidateCode.text=Cstr(ViewState("VNum")) then
          lblShow.text="<font color='red'>提示:验证通过</font>"
      Else
       lblShow.text="所填写的验证码与所给的不符"
      End If
  End Sub
</script>
<html>
<body>
<form runat="server">
  <div align="center">
    <table width="750">
      <!--DWLayoutTable-->
      <tr> 
        <td width="256" height="46">  </td>
        <td width="9"> </td>
        <td width="88"> </td>
        <td width="87"> </td>
        <td width="100"> </td>
        <td width="68"> </td>
        <td width="97"> </td>
      </tr>
      <tr> 
        <td height="21"></td>
        <td></td>
        <td colspan="3" valign="top"><asp:label ID="lblShow" runat="server"></asp:label></td>
        <td> </td>
        <td> </td>
      </tr>
      <tr> 
        <td height="14"></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr> 
        <td height="21"> </td>
        <td colspan="2" valign="middle">验证码:</td>
        <td valign="top"><asp:Image id="Image1" runat="server" ImageUrl="gif.aspx" /></td>
        <td> </td>
        <td> </td>
        <td> </td>
      </tr>
      <tr> 
        <td height="20"> </td>
        <td colspan="2" valign="top">输入验证码:</td>
        <td valign="top"><asp:textbox ID="txtValidateCode" runat="server" TextMode="SingleLine" /></td>
        <td colspan="2" valign="middle"><font color="#FF0000" size="2">*注意:区分大小写</font></td>
        <td> </td>
      </tr>
      <tr> 
        <td height="25"> </td>
        <td> </td>
        <td> </td>
        <td> </td>
        <td> </td>
        <td> </td>
        <td> </td>
      </tr>
      <tr> 
        <td height="19"> </td>
        <td> </td>
        <td> </td>
        <td valign="top"><asp:button ID="btnSubmit" runat="server" Text="比较" onclick="btnSubmit_click" /></td>
        <td> </td>
        <td> </td>
        <td> </td>
      </tr>
    </table>
  </div>
</form>
</body>
</html> 

9:05 | 评论 (0)

[转载]Asp.NET消息框的使用

 好象现在很多人在问在ASP.NET如何使用弹出消息框和,消息框确认的问题..
我想能和大家讨论一下..希望大能支持..

我想一般人都知道在客户諯使用弹出框的是不能用MesssageBox来实现的.
一般都使用以下几种方法.
1)   Button.Attributes.Add("onclick","javascript:return confirm('确定?');");
这种方法..现在使用最的多..
在www.csdn.net里有一文章就很好.
http://www.csdn.net/Develop/Read_Article.asp?Id=20892
大家可以看一下..会有很多收获.
2)另一个方法..我不知道其它人有没有这么用.不过我是这么用的..很偷懒的办法京是
<div id=div1 onclick="javascript:return confirm('确定?');"><asp:button id="Button1" runat="server" Text="Button"></asp:button></div>
这个一样能实现..而且不用增加服务器的动作...不过有没有其它后果..就不..知道了..
在DataGrid中一样在Button列中使用属性编辑器在文本(t)中写入
<div id=div1 onclick="javasciprt:return confrim(确定?')">删除</div>就能在DataGrid中实现删除确认的功能..当然如果每行删除不一样你就得用其它方法了.
http://www.csdn.net/Develop/Read_Article.asp?Id=20892
中一样有介绍.
3)可能有时候大家会这样的用处..就是你点击导入数据的Button的按钮后..希望能弹出一个alert('数据导入完成!')这样的信息.
这里就得用另外的方法了..可能很多人都知道就是使用.
Page.RegisterClientScriptBlock ();或Page.RegisterStartupScript();
这两一功能上相差不是很大...且配合.Page.IsClientScriptBlockRegistered()或Page.IsStartupScriptRegistered();来使用的
string scriptStr="<script language=javasciprt> alert('数据导放已完成')</"
sciprtStr+="sciprt>";
Page.RegisterStartupScript("alert1",sciprtStr);
就Ok了.
据说Page.RegisterClientScriptBlock ();比Page.RegisterStartupScript();好..
但我不知道原因,哪位能说一下最好啦.

9:02 | 评论 (1)

转帖]Visual C#的Excel编程

作者:wyhw 发表时间:2003-5-11 

很奇怪..wyhw的文章在其它网站有转贴,自己的网站却没有..不知道是不是同名同姓的?
-_-!


Excel是微软公司办公自动化套件中的一个软件,他主要是用来处理电子表格。Excel以其功能强大,界面友好等受到了许多用户的欢迎。在办公的时候,正是由于Excel的这么多的优点,许多重要的数据,往往以Excel电子表格的形式存储起来。这样就给程序员带来了一个问题,虽然Excel功能比较强大,但毕竟不是数据库,在程序中处理数据库中的数据比其处理Excel表格中的数据容易许多。那么如何用Visual C#读取Excel表格中的数据?在以前用Delphi编程的时候,对于不同的用户,他们对于打印的需求是不一样的,如果要使得程序中的打印功能适用于每一个用户,可以想象程序设计是十分复杂的。这时想到Excel,由于Excel表格的功能强大,又由于几乎每一台机器都安装了它,如果把程序处理的结果放到Excel表格中,这样每一个用户就可以根据自己的需要在Excel中定制自己的打印。这样不仅使得程序设计简单,而且又满足了诸多用户的要求,更加实用了。那么用Visual C#如何调用Excel,如何又把数据存放到Excel表格中?本文就来探讨一下上述问题的解决办法。

  一.程序设计及运行环境

   (1).微软视窗2000 服务器版

   (2)..Net Framework SDK Beta 2

   (3).Microsoft Data Access Component 2.6以上版本(MDAC2.6)

   (4).Office 2000套件 
  二.Visual C#读取Excel表格中的数据:

  本节将通过一个程序来介绍Visual C#读取Excel表格中的数据,并把数据以DataGrid的形式显示出来。

  (1).如何读取数据:

  其实读取Excel表格中的数据和读取数据库中的数据是非常类似的,因为在某种程度上Excel表格可以看成是一张一张的数据表。其二者的主要区别在于所使用的数据引擎不一样。在本文的程序中,通过下列代码实现读取Excel表格数据,具体如下:


//创建一个数据链接
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = c:\\sample.xls;Extended Properties=Excel 8.0" ;
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
string strCom = " SELECT * FROM [Sheet1$] " ;
myConn.Open ( ) ;
file://打开数据链接,得到一个数据集
OleDbDataAdapter myCommand = new OleDbDataAdapter ( strCom , myConn ) ;
file://创建一个 DataSet对象
myDataSet = new DataSet ( ) ;
file://得到自己的DataSet对象
myCommand.Fill ( myDataSet , "[Sheet1$]" ) ;
file://关闭此数据链接
myConn.Close ( ) ; 


  怎么样读取Excel表格中的数据其实和读取数据库中的数据没有什么实质上的区别。

  注释:这里读取的是C盘根目录下的"Sample.xls"文件。

  (2).用DataGrid来显示得到的数据集:

  在得到DataSet对象后,只需要通过下列二行代码,就可以把数据集用DataGrid显示出来了:


DataGrid1.DataMember= "[Sheet1$]" ;
DataGrid1.DataSource = myDataSet ; 

  (3).用Visual C#读取Excel表格,并用DataGrid显示出来的程序代码(Read.cs)和程序运行的界面:

  掌握了上面二点,水到渠成就可以得到以下代码:


using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Data.OleDb ;
public class Form1 : Form
{
private Button button1 ;
private System.Data.DataSet myDataSet ;
private DataGrid DataGrid1 ;
private System.ComponentModel.Container components = null ;

public Form1 ( )
{
file://初始化窗体中的各个组件
InitializeComponent ( ) ;
file://打开数据链接,得到数据集
GetConnect ( ) ;
}
file://清除程序中使用过的资源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null ) 
{
components.Dispose ( ) ;
}
}
base.Dispose ( disposing ) ;
}

private void GetConnect ( )
{
file://创建一个数据链接
string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = c:\\sample.xls;Extended Properties=Excel 8.0" ;
OleDbConnection myConn = new OleDbConnection ( strCon ) ;
string strCom = " SELECT * FROM [Sheet1$] " ;
myConn.Open ( ) ;
file://打开数据链接,得到一个数据集
OleDbDataAdapter myCommand = new OleDbDataAdapter ( strCom , myConn ) ;
file://创建一个 DataSet对象
myDataSet = new DataSet ( ) ;
file://得到自己的DataSet对象
myCommand.Fill ( myDataSet , "[Sheet1$]" ) ;
file://关闭此数据链接
myConn.Close ( ) ;
}
private void InitializeComponent ( )
{
DataGrid1 = new DataGrid ( ) ;
button1 = new Button ( ) ;
SuspendLayout ( ) ;
DataGrid1.Name = "DataGrid1";
DataGrid1.Size = new System.Drawing.Size ( 400 , 200 ) ;

button1.Location = new System.Drawing.Point ( 124 , 240 ) ;
button1.Name = "button1" ;
button1.TabIndex = 1 ;
button1.Text = "读取数据" ;
button1.Size = new System.Drawing.Size (84 , 24 ) ;
button1.Click += new System.EventHandler ( this.button1_Click ) ;

this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;
this.ClientSize = new System.Drawing.Size ( 400 , 280 ) ;
this.Controls.Add ( button1 ) ;
this.Controls.Add ( DataGrid1 ) ;
this.Name = "Form1" ;
this.Text = "读取Excle表格中的数据,并用DataGrid显示出来!" ;
this.ResumeLayout ( false ) ;

}
private void button1_Click ( object sender , System.EventArgs e )
{
DataGrid1.DataMember= "[Sheet1$]" ;
DataGrid1.DataSource = myDataSet ;

}
static void Main ( ) 
{
Application.Run ( new Form1 ( ) ) ;
}
}



  下图是程序编译后,运行结果:
http://www.yesky.com/20020313/jt-2002-3-13-image001.jpg

图01:用Visual C#读取"c:\sample.xls"的运行界面
  (4).总结:

  以上只是读取了Excel表格中"Sheet1"中的数据,对于其他"Sheet"中的内容,可以参照读取"Sheet1"中的程序,只作一点修改就可以了,譬如要读取"Sheet2"中的内容,只需要把"Read.cs"程序中的"Sheet1$"改成"Sheet2$"就可以了。

  三.Visual C#调用Excel表格,并在Excel表格中存储数据:

  在Visual C#中调用Excel表格,并不像读取Excel表格中的数据那么容易了,因为在Visual C#中调用Excel表格要使用到Excel的COM组件。如果你安装Office套件在"C"盘,那么在"C:\Program Files\Microsoft Office\Office"可以找到这个COM组件"EXCEL9.OLB",在《Visual C#如何使用Active X组件》一文中,这些COM组件都是非受管代码的,要在Visual C#中使用这些非受管代码的COM组件,就必须把他们转换成受管代码的类库。所以在用Visual C#调用Excel表格之前,必须完成从COM组件的非受管代码到受管代码的类库的转换。

  (1).非受管代码COM组件转换成受管代码的类库:

  首先把COM组件"EXCEL9.OLB"拷贝到C盘的根目录下,然后输入下列命令:


tlbimp excel9.olb 

  这样在C盘的根目录下面就产生了三个DLL文件:"Excel.dll"、"Office.dll"、"VBIDE.dll"。在产生了上面的三个文件后,这种转换就成功完成了。在下面的程序中,就可以利用这转换好的三个类库编写和Excel表格相关的各种操作了。

  (2).Visual C#打开Excel表格:

  在"Excel.dll"中定义了一个命名空间"Excel",在差命名空间中封装了一个类"Application",这个类和启动Excel表格有非常重要的关系,在Visual C#中,只需要下列三行代码就可以完成打开Excel表格的工作,具体如下:


Excel.Application excel = new Excel.Application ( ) ;
excel.Application.Workbooks.Add ( true ) ;

excel.Visible = true ; 

  但此时的Excel表格是一个空的表格,没有任何内容,下面就来介绍如何往Excel表格中输入数据。

  (3).往Excel表格中输入数据:

  在命名空间"Excel"中,还定义了一个类"Cell",这个类所代表的就是Excel表格中的一个下单元。通过给差"Cell"赋值,从而实现往Excel表格中输入相应的数据,下列代码功能是打开Excel表格,并且往表格输入一些数据。


Excel.Application excel = new Excel.Application ( ) ;
excel.Application.Workbooks.Add ( true ) ;
excel.Cells[ 1 , 1 ] = "第一行第一列" ; 
excel.Cells[ 1 , 2 ] = "第一行第二列" ; 
excel.Cells[ 2 , 1 ] = "第二行第一列" ; 
excel.Cells[ 2 , 2 ] = "第二行第二列" ; 
excel.Cells[ 3 , 1 ] = "第三行第一列" ; 
excel.Cells[ 3 , 2 ] = "第三行第二列" ; 
excel.Visible = true ; 

  (4). Visual C#调用Excel表格,并在Excel表格中存储数据的程序代码(Excel.cs):

  了解了上面的这些知识,得到完成上述功能的程序代码就显得比较容易了,具体如下:


using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.Data.SqlClient ;
public class Form1 : Form
{
private Button button1 ;
private System.ComponentModel.Container components = null ;
public Form1 ( )
{
file://初始化窗体中的各个组件
InitializeComponent ( ) ;
}
file://清除程序中使用的各个资源
protected override void Dispose ( bool disposing )
{
if ( disposing )
{
if ( components != null ) 
{
components.Dispose ( ) ;
}
}
base.Dispose( disposing ) ;
}
private void InitializeComponent ( )
{
button1 = new Button ( ) ;
SuspendLayout ( ) ;
button1.Location = new System.Drawing.Point ( 32 , 72 ) ;
button1.Name = "button1" ;
button1.Size = new System.Drawing.Size ( 100 , 30 ) ;
button1.TabIndex = 0 ;
button1.Text = "调用Excel文件!" ;
button1.Click += new System.EventHandler ( button1_Click ) ;

AutoScaleBaseSize = new System.Drawing.Size ( 5 , 13 ) ;

this.ClientSize = new System.Drawing.Size ( 292 , 273 ) ;
this.Controls.Add ( button1 ) ;
this.Name = "Form1" ;
this.Text = "如何用Visual C#调用Excel表格!" ;
this.ResumeLayout ( false ) ;

}
static void Main ( ) 
{
Application.Run ( new Form1 ( ) ) ;
}
private void button1_Click ( object sender , System.EventArgs e )
{
Excel.Application excel = new Excel.Application ( ) ;
excel.Application.Workbooks.Add ( true ) ;
excel.Cells[ 1 , 1 ] = "第一行第一列" ; 
excel.Cells[ 1 , 2 ] = "第一行第二列" ; 
excel.Cells[ 2 , 1 ] = "第二行第一列" ; 
excel.Cells[ 2 , 2 ] = "第二行第二列" ; 
excel.Cells[ 3 , 1 ] = "第三行第一列" ; 
excel.Cells[ 3 , 2 ] = "第三行第二列" ; 
excel.Visible = true ; 
}
}


  (5).编译源程序和程序运行界面:

  在经过了下列命令编译后:


Csc.exe /r:system.dll /r:system.windows.forms.dll /r:system.drawing.dll /r:excel.dll /r:office.dll /r:vbide.dll excel.cs 

  就可以得到"Excel.exe",运行后界面如下

http://www.yesky.com/20020313/jt-2002-3-13-image003.jpg
图02:Visual C#调用Excel表格,并存储数据的程序运行界面 

  四.Visual C#处理Office套件中的其他成员程序:

  本文虽然只介绍了Visual C#在处理Excel表格中经常遇到的一些问题的解决方法,但其实对Office套件的其他成员也有很强的借鉴意义,譬如Visual C#来处理Word文档,在调用Word文档的时候,必须先完成COM组件从非受管代码到受管代码的转换,Word的COM组件位"MSWORD9.OLB",经过转换后也会产生三个DLL文件,但分别是"Word.dll"、"Office.dll"、"VBIDE.dll"。其实在Visual C#中调用Word,也非常容易。只需要把调用Excel表格中的代码换成调用Word的代码就可以了,具体如下:


Word.Application word = new Word.Application ( ) ;
word.Application.Visible = true ; 

  不信你试一下,看看是否达到你的要求。对于针对Word的其他的操作,总体来说和对Excel表格的操作相类似。由于针对Word只是一个文档,程序对Word进行的操作是比较少的,所以就不一一介绍了。

  五.总结:

  本文介绍Visual C#来处理Excel表格的几种最常遇到的情况,虽然针对的只是Excel表格,但对其他Office套件中的成员也具有十分的借鉴意义。

8:59 | 评论 (0)

金额的格式化显示问题

由于要做金额的显示,需要对一个浮点数进行转换,保留2位小数。
例如
0  ->0.00
0.1->0.10
1  ->1.00
1.1->1.10

.ToString("#0.00");
.ToString("F2")

 

8:57 | 评论 (0)

[转载]DataGrid的首行进行合并单元格!

[原创]DataGrid的首行进行合并单元格!
希望下面的代码对大家有所帮助!
protected override void OnItemCreated(DataGridItemEventArgs e) 
      {      
      
         if ((ListItemType)e.Item.ItemType == ListItemType.Header) 
         {

            
            // 获得DataGrid的列数,并清除所有单元格
            int colcount = e.Item.Cells.Count;
            e.Item.Cells.Clear();

            // 新建一个单元格
            TableCell c = new TableCell();
            c.ColumnSpan = colcount;

            // 新建一个Label用于存放首行的文字         
            Label l=new Label();         
            l.Text = "这是首行文字";
         

            // 添加到DataGrid的首行
            c.Controls.Add(l);
            e.Item.Cells.AddAt(0, c);
         }         
      }

8:54 | 评论 (0)

2004年6月17日 #

关于台湾问题

        一看题目有点吓人,可能这样大的问题不是我这样的人可以妄加评论的。但是做为炎黄子孙。我觉得在这个中国人自己的事情上,我是有发表言论的自由的。

         如果美国千般阻挠中国人民维护领土完整时,它将遭遇的不仅仅是中国人民,国际社会的遣责。而是一但插手,必将遭受严厉的军事打击。做为一个找不到自己祖先的国家来说,这对于它来说意味着什么呢?

         美国军方应该明白中国的军力而不是军事实力。中国的军力是在从中华民国开始强大的人民的武装,与人民为敌是没有好下场的。历史早己证明了一切。

11:21 | 评论 (2)

2004年5月28日 #

在网上看到的一首诗_空

冰冷的阳光,透不过云层
美丽的梦想,在现实中夭折
挣扎
令人窒息

大千世界,翩然浮现
想从中寻找生活的真相
盼望着飞翔
终究发现自己没有翅膀

一切都是那么的未知,
那么的难以处置
放逐自己在一片无边无际里
是应该快乐的去想一件悲伤的事
还是应该悲伤的去做一件快乐的事

倔强着勇敢
茫然着坚持
犹豫着前进
终于明白什么是空虚
于是学会了在深蓝的夜色中俯视五彩斑斓的万家灯火

很深,很深的夜
一切,似乎都那么安详的
手心握不紧的疼痛,
只留给了自己看。
月光黯然
模糊了行迹
听说,有灵魂的人永远都不会消失...

清醒着无法入眠
窗外只剩微光的星辰
执拗着想要寻找属于自己的颜色
太阳升起来的时候
才发现,一身的黑暗

我把自己带进了海里
乞求着遇到那颗代表幸福的紫贝壳
却忘了
这个夏天
贝壳,都留在了沙滩上

从夜的起点,到梦的终点…….
泪水化成星星,
陨落,溶进了那片深蓝
无法分辨哪一滴海水才是你的眼泪
从此忘记了怎么哭泣
一切,来了去,去了空……

 

微笑,不一定幸福
流泪,不一定悲伤
用什么来化解回忆
人生,是否一定要有结局
只是
一切都将结束的时候 一切又重新开始了

 

4:55 | 评论 (1)


请不要发表可能给我们带来伤害的政治言论,谢谢配合