• 2004-10-05

    朝鲜的七个笑话 - [其它]

    1·集体农庄庄员郑龙万在河里捉到一条大鱼,高兴的回到家里和老婆说:
    “看,我们有炸鱼吃了!”
    没有油啊。”
    “那就煮!”
    “没锅。”
    “烤鱼!”
    “没柴。”
    郑龙万气死了,走到河边把鱼扔了回去。
    那鱼在水里划了一个半圆,上身出水,举起右鳍激动地高呼:“金正日万岁!”

    2·金正日的演讲:多年来,在美帝的压迫降下,我们的祖国一直处在悬崖的边缘。现在,我终于可以自豪地宣布,我们有了核弹头,我们伟大的朝鲜终于向前迈出了一大步。”

    3·美术馆里有一幅描写亚当和夏娃的画。
    一个英国人看了,说:“他们一定是英国人,男士有好吃的东西就和女士分享。”
    一个法国人看了,说:“他们一定是法国人,情侣裸体散步。”
    一个朝鲜人看了,说:“他们一定是朝鲜人,他们没有衣服,吃得很少,却还以为自己在天堂!

    4·金正日视察农场,看到猪儿乖乖,一时兴起站在猪中间照了张像。待到报纸准备发表时,编辑为照片的标题犯了难??
    “金正日同志和猪在一起”不好
    “猪和金正日同志在一起”也不好
    报纸出版后,照片下的说明文字是??
    “左起第三位是金正日同志”

    5·一个英国人,一个法国人,一个朝鲜人在一起聊天
    英国人:最幸福的事情就是冬天晚上回家,穿着羊毛裤坐在壁炉前面。
    法国人:你们英国人就是古板,最幸福的事情是和一个金发女郎一起去地中海度假,然后我们好和好散。
    朝鲜人:最幸福的事情就是半夜有人敲门,开门后
    :金成美,你被捕了。
    :你弄错了,金成美在隔壁。

    6·金正日和俄罗斯总统普京在莫斯科开会,休息时间两个人很无聊,就开始比谁的保膘更忠诚。普京先来,他把自己的报膘叫进来,推开窗(外面是20层楼)说:
    "伊万,从这里跳下去!”
    伊万哭着说:
    "你着么能这样呢,总统先生,我还有老婆孩子呐。”
    普京被感动了,流着泪说是自己不对,叫伊万走了,然后抡到金正日,他 也大声叫自己的保膘李明万。
    “李明万,从这里跳下去!”
    李明万二话不说就要往下跳,普京一把抱住他说:
    “你疯了?跳下去会死的!”
    李明万一边挣扎着要跳下去一边说:
    “放开我,混蛋,我还有老婆孩子呐。”

    7·平壤地铁中。
    “同志您好。”
    您好。”
    "请问您是委员会的同志吗?”
    "不是。”
    "您以前是吗?”
    "不是。”
    "您的直系亲属中有在委员会工作的吗?”
    “没有。”
    “那么请你把脚挪开,你踩着我了。”

  • 一、使用OWC

      什么是OWC?

      OWC是Office Web Compent的缩写,即Microsoft的Office Web组件,它为在Web中绘制图形提供了灵活的同时也是最基本的机制。在一个intranet环境中,如果可以假设客户机上存在特定的浏览器和一些功能强大的软件(如IE5和Office 2000),那么就有能力利用Office Web组件提供一个交互式图形开发环境。这种模式下,客户端工作站将在整个任务中分担很大的比重。

     

    <%Option Explicit
    Class ExcelGen
    Private objSpreadsheet
    Private iColOffset

    Private iRowOffset
    Sub Class_Initialize()
    Set objSpreadsheet = Server.CreateObject("OWC.Spreadsheet")
    iRowOffset = 2
    iColOffset = 2
    End Sub

    Sub Class_Terminate()
    Set objSpreadsheet = Nothing 'Clean up
    End Sub

    Public Property Let ColumnOffset(iColOff)
    If iColOff > 0 then
    iColOffset = iColOff
    Else
    iColOffset = 2
    End If
    End Property

    Public Property Let RowOffset(iRowOff)
    If iRowOff > 0 then
    iRowOffset = iRowOff
    Else
    iRowOffset = 2
    End If
    End Property Sub GenerateWorksheet(objRS)
    'Populates the Excel worksheet based on a Recordset's contents
    'Start by displaying the titles
    If objRS.EOF then Exit Sub
    Dim objField, iCol, iRow
    iCol = iColOffset
    iRow = iRowOffset
    For Each objField in objRS.Fields
    objSpreadsheet.Cells(iRow, iCol).Value = objField.Name
    objSpreadsheet.Columns(iCol).AutoFitColumns
    '设置Excel表里的字体
    objSpreadsheet.Cells(iRow, iCol).Font.Bold = True
    objSpreadsheet.Cells(iRow, iCol).Font.Italic = False
    objSpreadsheet.Cells(iRow, iCol).Font.Size = 10
    objSpreadsheet.Cells(iRow, iCol).Halignment = 2 '居中
    iCol = iCol + 1
    Next 'objField
    'Display all of the data
    Do While Not objRS.EOF
    iRow = iRow + 1
    iCol = iColOffset
    For Each objField in objRS.Fields
    If IsNull(objField.Value) then
    objSpreadsheet.Cells(iRow, iCol).Value = ""
    Else
    objSpreadsheet.Cells(iRow, iCol).Value = objField.Value
    objSpreadsheet.Columns(iCol).AutoFitColumns
    objSpreadsheet.Cells(iRow, iCol).Font.Bold = False
    objSpreadsheet.Cells(iRow, iCol).Font.Italic = False
    objSpreadsheet.Cells(iRow, iCol).Font.Size = 10
    End If
    iCol = iCol + 1
    Next 'objField
    objRS.MoveNext
    Loop
    End Sub Function SaveWorksheet(strFileName)

    'Save the worksheet to a specified filename
    On Error Resume Next
    Call objSpreadsheet.ActiveSheet.Export(strFileName, 0)
    SaveWorksheet = (Err.Number = 0)
    End Function
    End Class

    Dim objRS
    Set objRS = Server.CreateObject("ADODB.Recordset")
    objRS.Open "SELECT * FROM xxxx", "Provider=SQLOLEDB.1;Persist Security

    Info=True;User ID=xxxx;Password=xxxx;Initial Catalog=xxxx;Data source=xxxx;"
    Dim SaveName
    SaveName = Request.Cookies("savename")("name")
    Dim objExcel
    Dim ExcelPath
    ExcelPath = "Excel\" & SaveName & ".xls"
    Set objExcel = New ExcelGen
    objExcel.RowOffset = 1
    objExcel.ColumnOffset = 1
    objExcel.GenerateWorksheet(objRS)
    If objExcel.SaveWorksheet(Server.MapPath(ExcelPath)) then
    'Response.Write "<html><body bgcolor='gainsboro' text='#000000'>已保存为Excel文件.

    <a href='" & server.URLEncode(ExcelPath) & "'>下载</a>"
    Else
    Response.Write "在保存过程中有错误!"
    End If
    Set objExcel = Nothing
    objRS.Close
    Set objRS = Nothing
    %> 

     

      二、用Excel的Application组件在客户端导出到Excel或Word

      注意:两个函数中的“data“是网页中要导出的table的 id

    <input type="hidden" name="out_word" onclick="vbscript:buildDoc" value="导出到word" class="notPrint">
    <input type="hidden" name="out_excel" onclick="AutomateExcel();" value="导出到excel" class="notPrint"> 

      导出到Excel代码

    <SCRIPT LANGUAGE="javascript">
    <!--
    function AutomateExcel()
    {
    // Start Excel and get Application object.
    var oXL = new ActiveXObject("Excel.Application");
    // Get a new workbook.
    var oWB = oXL.Workbooks.Add();
    var oSheet = oWB.ActiveSheet;
    var table = document.all.data;
    var hang = table.rows.length;

    var lie = table.rows(0).cells.length;

    // Add table headers going cell by cell.
    for (i=0;i<hang;i++)
    {
    for (j=0;j<lie;j++)
    {
    oSheet.Cells(i+1,j+1).value = table.rows(i).cells(j).innerText;
    }

    }
    oXL.Visible = true;
    oXL.UserControl = true;
    }
    //-->
    </SCRIPT> 

      导出到Word代码

    <script language="vbscript">
    Sub buildDoc
    set table = document.all.data
    row = table.rows.length
    column = table.rows(1).cells.length

    Set objWordDoc = CreateObject("Word.Document")

    objWordDoc.Application.Documents.Add theTemplate, False
    objWordDoc.Application.Visible=True

    Dim theArray(20,10000)
    for i=0 to row-1
    for j=0 to column-1
    theArray(j+1,i+1) = table.rows(i).cells(j).innerTEXT
    next
    next
    objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("综合查询结果集") //显示表格标题

    objWordDoc.Application.ActiveDocument.Paragraphs.Add.Range.InsertBefore("")
    Set rngPara = objWordDoc.Application.ActiveDocument.Paragraphs(1).Range
    With rngPara
    .Bold = True //将标题设为粗体
    .ParagraphFormat.Alignment = 1 //将标题居中
    .Font.Name = "隶书" //设定标题字体
    .Font.Size = 18 //设定标题字体大小
    End With
    Set rngCurrent = objWordDoc.Application.ActiveDocument.Paragraphs(3).Range
    Set tabCurrent = ObjWordDoc.Application.ActiveDocument.Tables.Add(rngCurrent,row,column)

    for i = 1 to column

    objWordDoc.Application.ActiveDocument.Tables(1).Rows(1).Cells(i).Range.InsertAfter theArray(i,1)
    objWordDoc.Application.ActiveDocument.Tables(1).Rows(1).Cells(i).Range.ParagraphFormat.alignment=1
    next
    For i =1 to column
    For j = 2 to row
    objWordDoc.Application.ActiveDocument.Tables(1).Rows(j).Cells(i).Range.InsertAfter theArray(i,j)
    objWordDoc.Application.ActiveDocument.Tables(1).Rows(j).Cells(i).Range.ParagraphFormat.alignment=1
    Next
    Next

    End Sub
    </SCRIPT> 

      三、直接在IE中打开,再存为EXCEL文件

      把读出的数据用<table>格式,在网页中显示出来,同时,加上下一句即可把EXCEL表在客客户端显示。

    <%response.ContentType ="application/vnd.ms-excel"%> 

      注意:显示的页面中,只把<table>输出,最好不要输出其他表格以外的信息。

      四、导出以半角逗号隔开的csv

      用fso方法生成文本文件的方法,生成一个扩展名为csv文件。此文件,一行即为数据表的一行。生成数据表字段用半角逗号隔开。(有关fso生成文本文件的方法,在此就不做介绍了)

      CSV文件介绍 (逗号分隔文件)

      选择该项系统将创建一个可供下载的CSV 文件; CSV是最通用的一种文件格式,它可以非常容易地被导入各种PC表格及数据库中。

      请注意即使选择表格作为输出格式,仍然可以将结果下载CSV文件。在表格输出屏幕的底部,显示有 "CSV 文件"选项,点击它即可下载该文件。

      如果您把浏览器配置为将您的电子表格软件与文本(TXT)/逗号分隔文件(CSV) 相关联,当您下载该文件时,该文件将自动打开。下载下来后,如果本地已安装EXCEL,点击此文件,即可自动用EXCEL软件打开此文件。

  • 我们在进行ASP.NET开发时,经常会用到一些javascript脚本,比如:

    private void Button1_Click(object sender, System.EventArgs e)
    {
    Response.Write( "<script language='javascript'>alert('OK');</script>") ;
    }

    经常是重复的书写这些脚本,如果我们能做成一个相应的函数就好了,直接就可以拿来使用。很多人都有自己的一些javascript的函数,但是大部分向这样的:

    /// <summary>
    /// 服务器端弹出alert对话框
    /// </summary>
    /// <param name="str_Message">提示信息,例子:"请输入您姓名!"</param>
    /// <param name="page">Page类</param>
    public void Alert(string str_Message,Page page)
    {
    if(!page.IsStartupScriptRegistered ("msgOnlyAlert"))
    {
    page.RegisterStartupScript("msgOnlyAlert","<script>alert('"+str_Message+"');</script>");
    }
    }

    但是,用的时候,每次都要继承这个类,用起来还是有些麻烦,如果函数是静态的函数,类是静态的类的话,我们不要继承就可以使用。但是我们怎么写呢?

    看看这段代码

    #region public static void MessageBox( Page page, string msg )
    ///
    /// 弹出对话框
    ///
    /// 当前页面的指针,一般为this
    /// 消息
    public static void MessageBox( Page page, string msg )
    {
    StringBuilder StrScript = new StringBuilder();
    StrScript.Append( "<script language=javascript>" );
    StrScript.Append( "alert('"+ msg +"');" );
    StrScript.Append( "</script>" );
    if ( ! page.IsStartupScriptRegistered( "MessageBox" ) )
    {
    page.RegisterStartupScript( "MessageBox", StrScript.ToString() );
    }
    }
    #endregion

    这样的话我们就能方便使用很多已有的js脚本。

    PS:其实很多常用的方法都能写成静态函数进行调用的。偶再附几个例子作为一个参考。

    MD5加密:

    ///
    /// MD5 Encrypt
    ///
    /// text
    /// md5 Encrypt string
    public string MD5Encrypt(string strText)
    {
    MD5 md5 = new MD5CryptoServiceProvider();
    byte[] result = md5.ComputeHash(System.Text.Encoding.Default.GetBytes(strText));
    return System.Text.Encoding.Default.GetString(result);
    }

    取指定长度的随机数:

    #region public static string GetRandNum( int randNumLength )

    ///
    /// 取得随机数
    ///
    /// 随机数的长度
    ///
    public static string GetRandNum( int randNumLength )
    {
    System.Random randNum = new System.Random( unchecked( ( int ) DateTime.Now.Ticks ) );
    StringBuilder sb = new StringBuilder( randNumLength );
    for ( int i = 0; i < randNumLength; i++ )
    {
    sb.Append( randNum.Next( 0, 9 ) );
    }
    return sb.ToString();
    }

    #endregion

  • 网上有很多人问关于DataGrid的自动编号问题,但在论坛中我已经回复过好几次,但还是不断有人问

    序号

    内容

    1

    Taye

    2

    BOx

    3

    Glass

    4

    StarCraft


    一、正序

    AAllowPaging=False情况下

    <asp:DataGrid id="DataGrid1" runat="server">
        <Columns>
         <asp:TemplateColumn>
          <ItemTemplate>
           <%# Container.ItemIndex + 1%>
          </ItemTemplate>
         </asp:TemplateColumn>
        </Columns>
     </asp:DataGrid>


    就可以实现

    不过更有趣的方法是使用这个方法

     <asp:DataGrid id="DataGrid1" runat="server">
        <Columns>
         <asp:TemplateColumn>
          <ItemTemplate>
           <%# this.DataGrid1.Items.Count + 1%>
          </ItemTemplate>
         </asp:TemplateColumn>
        </Columns>
     </asp:DataGrid>

     

    也许有些人会觉得很奇怪为什么Items.Count会这样,而不是出来全部总合..但如果你了解绑定的过程时就容易理解.
    [
    从上面来看就是在ItemCreated事件中进行绑定所以得到的Items.Count刚好是当前的序号]

    B
    AllowPaging="True"
    如果你DataGrid支持分页则可以如下

    <asp:DataGrid id="DataGrid1" runat="server" AllowPaging="True">
        <Columns>
         <asp:TemplateColumn>
          <ItemTemplate>
           <%# this.DataGrid1.CurrentPageIndex * this.DataGrid1.PageSize + Container.ItemIndex + 1%>
          </ItemTemplate>
         </asp:TemplateColumn>
        </Columns>
    </asp:DataGrid>

     

    二、倒序的方法

    序号

    内容

    4

    Taye

    3

    BOx

    2

    Glass

    1

    StarCraft

    由上面可以知道使用
    this.DataGrid1.Items.Count -
    Container.ItemIndex + 1方法是不可能实现的,得到值而且全会为1
    分页的情况下更是一样.所以一开始我们就要取得数据源的行数

    .cs

                 private int rowscount = 0;

             protected int RowsCount

             {

                  get{ return rowscount;}

                  set{ this.rowscount = value; }

             }

        

             private void Page_Load(object sender, System.EventArgs e)

             {

                  // 在此处放置用户代码以初始化页面

                  if(!IsPostBack)

                       this.BindData();

             }

     

             private void BindData()

             {

                  SqlConnection cn = new SqlConnection("server=(local);database=NorthWind;uid=sa;pwd=");

                  string str=@"SELECT Employees.EmployeeID, Orders.EmployeeID

                                     FROM Employees INNER JOIN

                           Orders ON Employees.EmployeeID = Orders.EmployeeID ";

     

                  SqlDataAdapter sqlda = new SqlDataAdapter(str,cn);

                  DataSet ds = new DataSet();

     

                  sqlda.Fill(ds);

     

                  this.RowsCount = ds.Tables[0].Rows.Count;

     

                  this.DataGrid1.DataSource = ds;

                  this.DataGrid1.DataBind();

     

             }



    .aspx

    <asp:DataGrid id="DataGrid1" runat="server" AllowPaging="True">

                                <Columns>

                                       <asp:TemplateColumn>

                                              <ItemTemplate>

                                                     <%# RowsCount - DataGrid1.CurrentPageIndex * DataGrid1.PageSize - Container.ItemIndex %>

                                              </ItemTemplate>

                                       </asp:TemplateColumn>

                                </Columns>

                         </asp:DataGrid>

     

     当然如果是不是分页的情况一下更容易实现了.

  • 近来,在开发ISO文件管理系统的时候,曾经遇到过要将ASPX直接输出到EXCEL的需求,现将经验所得与大家分享。

    其实,利用ASP.NET输出指定内容的WORD、EXCEL、TXT、HTM等类型的文档很容易的。主要分为三步来完成。

    一、定义文档类型、字符编码

            Response.Clear();
            Response.Buffer= true;
            Response.Charset="utf-8";

            //下面这行很重要,  attachment 参数表示作为附件下载,您可以改成 online在线打开

           //filename=FileFlow.xls 指定输出文件的名称,注意其扩展名和指定文件类型相符,可以为:.doc || .xls || .txt ||.htm

            Response.AppendHeader("Content-Disposition","attachment;filename=FileFlow.xls");
            Response.ContentEncoding=System.Text.Encoding.GetEncoding("utf-8");

            //Response.ContentType指定文件类型 可以为application/ms-excel || application/ms-word || application/ms-txt || application/ms-html || 或其他浏览器可直接支持文档

            Response.ContentType = "application/ms-excel";
            this.EnableViewState = false;

    二、定义一个输入流

            System.IO.StringWriter oStringWriter = new System.IO.StringWriter();
            System.Web.UI.HtmlTextWriter oHtmlTextWriter = new System.Web.UI.HtmlTextWriter(oStringWriter);

    三、将目标数据绑定到输入流输出

            this.RenderControl(oHtmlTextWriter);

            //this 表示输出本页,你也可以绑定datagrid,或其他支持obj.RenderControl()属性的控件

            Response.Write(oStringWriter.ToString());
            Response.End();

    总结:本例程在Microsoft Visual Studio .NET 2003平台下测试通过,适用于C#和VB,当采用VB的时候将 this 关键字改成 me 。

  • 摘要:
    本文深入详细的介绍了Duwamish网上电子书店例程的结构框架,并详细的分析了该结构的若干特点和设计模式。

    目录:
    引言
    Duwamish介绍
    结构分析
    设计思想
    代码示例
    总结
    作者

    引言:
    能够作为Visual Studio .Net附带的例子,Duwamish一定包含了微软.Net设计队伍希望向开发者传达的某些信息,而事实上,Duwamish也的确能够称作是一个.Net开发者学习的经典示例,无论是从其设计架构,编程技巧或代码风格,都向我们展示了一个标准的.Net企业级应用程序所应该具有的特点。所以,通过研究Duwamish示例,高手能够领悟到.Net应用架构的设计思想,低手能够学习到.Net的编程技巧,实在是老少皆宜。 :)
    不过,本文的目的更多的是针对中级.Net学习者,这类读者往往已经熟悉了C#或者是VB.NET的语法,会用一些基本的类库,并已经会做一些比较小的程序。但是当他们开始着手开发一个真正具有实用价值的企业级应用的时候,却有种无处下手的感觉。如果你正巧属于这类学习者,请跟着我深入到Duwamish的世界中去,相信你一定会得到收获。

    Duwamish介绍:
    Microsoft公司每次推出新技术,总是会相应的推出一些公开源代码的应用范例来说明该项新技术的特点,而开发者也能通过研究该范例的代码来达到迅速掌握新技术并与以实施的目的。Microsoft通过对一个虚拟的在网上销售图书的电子商务公司网上销售系统应用的创建,向用户展现了典型的网上购物实践中最为普遍的电子商务企业对客户 (B2C) 模式,它包括成员资格、帐户管理、购物车、搜索和结帐过程等基本功能。Duwamish经历了三个版本4.0,5.0和7.0版,每一个版本的发布都印证了技术进步的过程,每一个版本都代表了当时最先进的技术动向。这里将要研究和讨论的是Duwamish的最高版本7.0版,经历了COM/COM+技术以及Microsoft DNA架构的Duwamish,在最新的版本中完全采用了.Net技术及架构,比以前显得更加先进和成熟。

    如果您安装了Visual Studio .Net的话,您可以在您的VS.Net 的Enterprise Samples目录下找到并安装它,例如:C:\Program Files\Microsoft Visual Studio .NET\Enterprise Samples\,或者您还可以到http://astradigital.com/Duwamish7Vb/这个地址去看看它在Internet的一个演示实例。其它有关Duwamish的详细介绍资料请参考Visual Studio .Net附带的MSDN帮助,地址是:ms-help://MS.VSCC/MS.MSDNVS.2052/dwamish7/html/vtoriDuwamishBooks70.htm,这里不再赘述。

    Duwamish结构分析:
    Duwamish 7.0 是一个典型的N层架构,其结构分为四个逻辑层:
    Web 层
    Web 层为客户端提供对应用程序的访问。这一层是作为 Duwamish.sln 解决方案文件中的 Web 项目实现的。Web 层由 ASP.NET Web 窗体和代码隐藏文件组成。Web 窗体只是用 HTML 提供用户操作,而代码隐藏文件实现各种控件的事件处理。
    业务外观层
    业务外观层为 Web 层提供处理帐户、类别浏览和购书的界面。这一层是作为 Duwamish.sln 解决方案文件中的 BusinessFacade 项目实现的。业务外观层用作隔离层,它将用户界面与各种业务功能的实现隔离开来。除了低级系统和支持功能之外,对数据库服务器的所有调用都是通过此程序集进行的。
    业务规则层
    业务规则层是作为 Duwamish.sln 解决方案文件中的 BusinessRules 项目实现的,它包含各种业务规则和逻辑的实现。业务规则完成如客户帐户和书籍订单的验证这样的任务。
    数据访问层
    数据访问层为业务规则层提供数据服务。这一层是作为 Duwamish.sln 解决方案文件中的 DataAccess 项目实现的。
    比较令人困惑的是其中的业务外观层和业务规则层,很多人在学习N层结构开发的时候,听得最多的是三层结构,分别为:表示层,中间层和数据层。Duwamish的WEB层和数据访问层比较好理解,也就是传统意义上的表示层和数据层,那么业务外观层和业务规则层和我们熟悉的中间层有什么联系呢?

    设计思想:
    在Web应用程序中,有部分操作只是简单的从数据库根据条件提取数据,不需要经过任何处理,而直接将数据显示到网页上,比如查询某类别的图书列表。而另外一些操作,比如计算定单中图书的总价并根据顾客的级别计算回扣等等,这部分往往有许多不同的功能的类,操作起来也比较复杂。我们可以先想象一下,如果我们采用三层结构,这些商业逻辑一般是会放在中间层,那么对内部的这些大量种类繁多,使用方法也各异的不同的类的调用任务,就完全落到了表示层。这样势必会增加表示层的代码量,将表示层的任务复杂化,和表示层只负责接受用户的输入并返回结果的任务不太相称,并增加了层与层之间的耦合程度。
    为了解决这个问题,我们先来看看《设计模式》一文中对Facade模式的描述:
    意图:
    为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
    适用性:
    当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
    客户程序与抽象类的实现部分之间存在着很大的依赖性。引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
    当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。
    结构图:

    上文提出的这个矛盾,正好和设计模式中Facade模式中所描述的需要解决的问题非常吻合,在《设计模式》中提出的解决的办法就是引入一个Facade对象,让这个Fa&ccedil;ade来负责管理系统内部类的调用,并为表示层提供了一个单一而简单的接口。这个Fa&ccedil;ade对象,在我们的Duwamish的设计中,就是BusinessFacade(业务外观)层。
    以下是Duwamish的结构关系图:

    我们从图中可以清楚的看到,浏览器首先调用的是表示层WEB,然后WEB将请求发送给业务外观层,业务外观层对请求进行初步的处理,判断是否需要调用业务规则层,还是直接调用数据访问层获取数据。最后由数据访问层访问数据库并按照来时的步骤返回结果到浏览器(对于图中涉及到其它的结构模块以后会分别予以详细介绍)。

    代码示例:
    以下是两种不同处理路径的代码示例:
    获取商品目录
    表示层调用业务外观层:
    productSystem = new ProductSystem();
    categorySet = productSystem.GetCategories(categoryID);
    业务外观层直接调用数据层:
    public CategoryData GetCategories(int categoryId)
    {
        if ( dsCommand == null )
        {
            throw new System.ObjectDisposedException( GetType().FullName );
        }            
         return FillCategoryData("GetCategories", "@CategoryId", categoryId);
    }
    
    添加定单
    表示层调用业务外观层:
    public void AddOrder()
    {
        ApplicationAssert.CheckCondition(cartOrderData != null, "Order requires data", 
    		ApplicationAssert.LineNumber);
        ApplicationLog.WriteTrace("Duwamish7.Web.Cart.AddOrder:\r\nCustomerId: " +
               cartOrderData.Tables[OrderData.CUSTOMER_TABLE].Rows[0][OrderData.PKID_FIELD].ToString());
        cartOrderData = (new OrderSystem()).AddOrder(cartOrderData);
    }
    
    业务外观层调用业务规则层:
    public OrderData AddOrder(OrderData order)
    {
        ApplicationAssert.CheckCondition(order != null, "Order is required",
    	ApplicationAssert.LineNumber);
        
        (new BusinessRules.Order()).InsertOrder(order);
        return order;
    }
    
    业务规则层调用数据层:
    public bool InsertOrder(OrderData order)
    {    
    	//此处省略复杂的处理逻辑
        if ( isValid )
        {
            using (DataAccess.Orders ordersDataAccess = new DataAccess.Orders())
            {
                return (ordersDataAccess.InsertOrderDetail(order)) > 0;
            }
        }
        else
            return false;
    }
    

    总结:
    通过分析Duwamish7的结构设计,我们掌握了Fa&ccedil;ade模式,并学习到了如何通过Fa&ccedil;ade模式对应用结构进行改进,同时了解了Duwamish7的基本概念和处理流程,为以后深入分析和学习Duwamish7的的其它部分打下了一个基础。

    作者:
    卢彦
  •  戴泽峰

    概要

    本文结合示例讲述了在ASP.net应用程序中如何利用客户端的Javascript脚本提高程序的执行效率并实现更多的功能。

    一、ASP.Net与Javascript

    .Net是微软公司下一代的战略核心,ASP.Net是.Net战略在Web开发方面的具体实现。它继承了ASP的简单性和易用性,同时克服了ASP程序结构化较差,难于阅读和理解的缺点。特别是服务器端控件和事件驱动模式的引入,使得Web应用程序的开发更接近于过去桌面程序的开发。

    在各种各样介绍ASP.Net的文章和书籍中,都把重点放在了服务器控件和.Net Framework SDK上,因为这是ASP.Net中最新和最具革命性的改进;与此相反,在过去的Web开发中占据重要地位的客户端脚本Javascript(也包括VBScript)则鲜有提及,似乎有了服务器端程序,已经不需要客户端脚本了。但是,服务器端的程序毕竟需要一次浏览器与Web服务器的交互,对于ASP.Net来说,就是一次页面的提交,需要来回传送大量的数据,而很多工作,比如输入验证或者删除确认等,完全可以用Javascript来实现。因此,探讨在ASP.Net中如何使用Javascript仍然很有必要。


    二、Javascript的应用示例

    1.为页面上的某个服务器控件添加Javascript事件

    服务器控件最终生成的仍然是普通的HTML,比如<asp:textbox>生成input text。表单中的每个HTML控件都有它自己的Javascript事件,比如Textbox有onchange事件,Button有onclick事件,Listbox有onchange事件等。要想为服务器控件添加客户端的事件,需要用到Attributes属性。Attributes属性是所有的服务器控件都有的一个属性,它用来为最终生成的HTML添加自定义的一些标记。假设Web Form上有一个保存按钮btnSave,希望在用户点此按钮时提示用户是否确实要保存(比如一旦保存就无法恢复等),则应在Page_Load事件中添加如下代码:

    if not page.isPostBack() then

    btnSave.Attributes.Add(“onclick”,”Javascript:return confirm(‘Are you sure to save?’);”)

    end if

    要注意的是‘return’,这是不可省的,否则即使用户点了取消,数据仍然会保存。


    2.为Datagrid中的每一行添加Javascript事件

    假设Datagrid的每一行有一个删除按钮,希望在用户点此按钮时提示用户是否确实要删除此条记录,以防用户点错了行,或仅仅是无意中点了删除按钮。

    无论这个删除按钮是什么名字,都不能象上个例子那样直接引用,因为每一行都有这样一个按钮,它们是Datagrid中的子控件。在这种情况下,需要用到Datagrid的OnItemDataBound事件。OnItemDataBound事件发生在Datagrid的每一行数据绑定到Datagrid之后(即一行激发一次)。首先在Datagrid的声明中添加如下代码:

    <asp:datagrid id="grd1" runat="server" OnItemDataBound = "ItemDataBound" >

    …Columns definition here

    </asp:datagrid> 此处说明OnItemDataBound事件发生时调用ItemDataBound方法,在代码后置文件中添加此方法的定义:


    Sub ItemDataBound(ByVal sender As Object, ByVal e As DataGridItemEventArgs)

    If e.Item.ItemType <> ListItemType.Header And e.Item.ItemType <> ListItemType.Footer Then

    Dim oDeleteButton As LinkButton = e.Item.Cells(5).Controls(0)

    oDeleteButton.Attributes("onclick") = "javascript:return Confirm ('Are you sure you want to delete" & DataBinder.Eval(e.Item.DataItem, "m_sName") & "?')"

    End If

    End Sub

    由于Datagrid的标题行和脚注行也会激发此事件,所以首先判断激发此事件的行不是标题行和脚注行。这里假设Delete按钮位于Datagrid的第6列(第一列是0),且Datagrid的Datasource中包含名为”m_sName”的列


    3.引用编辑状态下的Datagrid中的控件

    Datagrid的内置编辑功能使得当记录的字段较少时的一种编辑方法。用户不必进入一个单独的页面编辑记录,而是直接点编辑按钮就可以使当前行进入编辑模式。而另一方面,有一些Javascript程序需要引用控件的名称。比如,很多程序在需要用户输入日期时都提供一个日期控件以保证日期格式的合法性,当用户点控件图标时弹出一个新窗口供用户选择日期。此时需要把显示日期的文本框的ID提供给新窗口,以便当用户选择日期后值可以回填到文本框中。

    如果是普通的服务器文本框控件,它的ID与生成的HTML输入框的ID是相同的;但是在Datagrid的编辑状态下,两个ID并不相同(其道理与上例相同),这就需要用到控件的ClientID属性。

    Protected Sub ItemEdit(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs)

    Dim sDateCtrl as string

    sDateCtrl = grd1. Items (e.Item.ItemIndex) . Cells(2). FindControl("txtDate") . ClientID

    End Sub

    这里假设ItemEdit方法是Dategrid的OnItemEdit事件处理程序,同时在Datagrid的第三列包含一个名为txtDate的服务器文本框控件。


    4.引用ASP.Net自动生成的Javascript程序

    所谓的“服务器端控件”是针对开发人员的,在生成的HTML源程序中并没有服务器和客户端之分,都是标准的HTML,DHTML和Javascript。它之所以能响应用户的输入是因为每个控件的事件处理程序最终都生成了一段脚本,此脚本重新提交页面使得Web Server有机会再次响应并作出处理。通常情况下我们不必知道此脚本是什么也不必直接调用此脚本,但在有些情况下,适当地调用此脚本可以简化许多工作。请看下面两个例子。

    ● 点Datagrid的任一位置以选中一行

    Datagrid提供了一种内置的选择按钮,当点此按钮时选中当前行(可以设置SelectedItemStyle属性以使当前行有不同的外观)。但用户可能更习惯于点任意一个位置都能选中一行,如果完全自己实现这个功能相当烦琐。一个好的思路是添加一个选择按钮,但使此列隐藏,当点任一行时调用此按钮产生的Javascript脚本。

    Sub Item_Bound(ByVal sender As Object, ByVal e As DataGridItemEventArgs )

    Dim itemType As ListItemType

    itemType = CType(e.Item.ItemType, ListItemType)

    If (itemType <> ListItemType.Header) And _

    (itemType <> ListItemType.Footer) And _

    (itemType <> ListItemType.Separator) Then

    Dim oSelect As LinkButton = CType(e.Item.Cells(5).Controls(0), LinkButton)

    e.Item.Attributes("onclick") = Page. GetPostBackClientHyperlink (oSelect, "")


    End Sub

    这里假设选择按钮位于第6列。e.Item代表了一行,从生成的HTML上看就是在每个<tr>里增加了一个onclick事件。Page.GetPostBackClientHyperLink方法返回页面中LinkButton控件产生的客户端脚本,其中第一个参数是Linkbutton控件,第二个参数是传递给此控件的参数,通常为空。如果不是LinkButton控件,有一个类似的函数GetPostBackClientEvent,读者可以参考MSDN。

    服务器产生的脚本与手工添加的脚本冲突

    服务器控件的服务器事件一般对应到客户端控件的相应事件,如Dropdownlist的SelectedIndexChanged事件对应HTML <Select>的onchange事件。如果你要手工增加一个onchange事件,则会在客户端产生两个onchange,浏览器就会忽略掉一个。比如用户希望每当改变了Dropdownlist中的选项就保存到数据库(虽然不是很常见,但确实有这种需要),但同时还希望提醒用户是否确实要做保存。显然,保存的代码应该放在SelectedIndexChanged事件中,而提醒的工作应该手工加一段onchange事件。结果就是两个onchange只能执行一个。正确的方法应该是添加一个不可见的保存按钮,在手工增加的onchange事件中调用此按钮生成的程序。

    Page_Load方法如下:

    Dim sCmd as string

    sCmd=Page.GetPostBackClientHyperlink(btnUpdate, "")

    If not page.isPostback then

    Dropdownlist1.Attributes.add("onchange","ConfirmUpdate(""" & sCmd & """)")

    End if


    ConfirmUpdate函数如下

    <Script language=”javascript”>

    function ConfirmUpdate(cmd){

    if confirm(“Are you sure to update?”)

    eval(cmd);

    }

    </Script>

    这里利用了Javascript eval函数来调用一个字符串中包含的命令。需注意的是包含命令的字符串不能用单引号括起来,因为自动生成的脚本中包括单引号,所以这里用两个双引号表示字符串本身的双引号。

    三、结束语

    以上简单讨论了在ASP.Net中插入Javascript的几种情况。合理地在服务器程序中插入客户端的Javascript脚本,可以提高程序的运行效率并提供更友好的用户界面。

  • 从 ASP.NET 服务器控件插入客户端脚本

    Scott Mitchell

    2003 年 8 月

    适用于:
        Microsoft® ASP.NET

    前提条件:本文假设读者熟悉 ASP.NET。

    难度: 2

    摘要:尽管从技术角度讲,ASP.NET 服务器控件的所有功能都可以在服务器端执行,但通常情况下通过添加客户端脚本可以大大增强服务器控件的可用性。本文将探讨服务器控件发送客户端脚本的两种方法,还将构建两个使用这些技术的服务器控件:PopupGreeting,一个在首次加载的 Web 页面上显示带有特定消息的客户端模式对话框的服务器控件;ConfirmButton,一个增强的 Button Web 控件,如果用户点击此按钮,则在发回 Web 窗体前向用户显示一个 JavaScript confirm() 的对话框。(本文包含一些指向英文站点的链接。)

    下载 InjectingClientSideScript.msi

    目录

    简介
    使用 RegisterStartupScript() 和 RegisterClientScriptBlock() 添加客户端脚本块
    探讨 IsStartupScriptRegistered() 和 IsClientScriptBlockRegistered()
    从 ASP.NET 服务器控件发送客户端脚本块
    发送 ASP.NET 服务器 Web 控件的 HTML 属性
    小结

    简介

    尽管从技术角度讲,Microsoft® ASP.NET 服务器控件的所有功能都可以在服务器端执行,但通常情况下通过添加客户端脚本可以大大增强服务器控件的可用性。例如,ASP.NET 验证 Web 控件可以在服务器端执行所有的验证检查。但是,对于高版本浏览器,验证 Web 控件也会发送客户端脚本,以在客户端进行验证。这就是说,这些浏览器的用户可以获得响应效果更好的动态体验。

    在开发 ASP.NET 服务器控件时,您不妨问问自己,如何才能通过使用客户端脚本来增强可用性。一旦找到可行的方案,其他要做的就是增强服务器控件的功能,以使其发送合适的客户端脚本。

    ASP.NET 服务器控件可以发送两种客户端脚本:

    • 客户端脚本块
    • 客户端 HTML 属性

    客户端脚本块通常是用 JavaScript 编写的,其中通常包含在发生特定的客户端事件时执行的函数。客户端 HTML 属性提供将客户端事件与客户端脚本联系在一起的方法。例如,以下的 HTML 页面中包含了客户端脚本块,脚本块中包含了名为 doClick() 的函数。该页面同时还包含一个按钮(通过 <input> HTML 元素创建),这个按钮的 onclick 属性与 doClick() 函数绑定。也就是说,只要用户单击该按钮,就开始执行 doClick() 函数中的客户端代码。在本示例中,将显示一个弹出式对话框(图 1)。

    <html>
      <body>
        <form>
          <script language="JavaScript">
          <!--
             function doClick() {
                alert("You clicked me!");
             }
          // -->
          </script>
    
          <input type="button" onclick="doClick()" value="Click Me!" />
        </form>
      </body>
    </html>
    

    图 1 是单击“Click Me!”按钮时 HTML 页面的屏幕快照。

    图 1:单击“Click Me!”按钮时显示的弹出式对话框

    对于以上 HTML 页面中的客户端脚本,有几点值得注意。首先,客户端脚本块包含在 HTML 注释(<!---->)中。之所以这样,是因为如果不将脚本块放入 HTML 注释中,那些不能识别脚本的旧式浏览器就会显示 <script> 块的内容。此外,还要注意,脚本块中 HTML 注释的结束标记前有一个 JavaScript 注释,即 //。这是因为旧版本的 Netscape 在遇到 --> 时,会抛出 JavaScript 分析异常,因此必须将其注释掉。幸运的是,现代的浏览器已不需要这一额外操作,所以在为 Intranet 或其他由浏览器控制的环境开发 Web 页面时,您就不必采取此类预防措施了。

    如果您对客户端脚本不是很熟悉,alert(string) 函数的作用就是显示一个模式弹出式对话框,对话框中包含的消息由 string 参数指定。所有 HTML 元素都有若干个可以绑定一段客户端 JavaScript 代码的客户端属性(例如,onclickonmouseoveronmouseoutonfocusonblur 等等)。例如,在上面的 HTML 页面中,<input> 元素的 onclick 属性绑定到 doClick() 函数,因此在单击该按钮时将执行 doClick() 函数。有关 JavaScript 事件及其关联的 HTML 属性的列表,请参阅 Introduction to Dynamic HTML 一文。有关客户端 JavaScript 的详细信息,请参阅 HTML and Dynamic HTML 一文。

    在本文中,我们将学习如何在 ASP.NET 服务器控件中发送客户端脚本块和 HTML 元素属性。我们首先讨论如何使用 System.Web.UI.Page 类中的两个方法来向 ASP.NET Web 页面添加客户端脚本块,这两个方法是 RegisterStartupScript()RegisterClientScriptBlock()。掌握这一知识后,我们将构建一个简单的服务器控件,让这个控件在每次加载页面时显示一个客户端弹出式对话框。之后,我们再来了解如何将 HTML 属性添加到 ASP.NET 服务器控件的 HTML 元素。最后,我们将归纳所有知识,实际构建一个 ConfirmButton Web 控件,当单击这个控件时,将向用户提示一个对话框,询问用户是否要继续。

    使用 RegisterStartupScript() 和 RegisterClientScriptBlock() 添加客户端脚本块

    System.Web.UI.Page 类包含的两个方法可以将客户端脚本代码发送到由 ASP.NET Web 页面提供的 HTML 中:

    • RegisterStartupScript(key, script)
    • RegisterClientScriptBlock(key, script)

    这两个方法都接受两个字符串作为输入。第二个参数 script 是要插入到页面中的客户端脚本,包括 <script> 的起始标记和终止标记。第一个参数 key 是插入的客户端脚本的唯一标识符。

    这两个方法唯一的不同之处在于从“何处”发送脚本块。RegisterClientScriptBlock() 在 Web 窗体的开始处(紧接着 <form runat="server"> 标识之后)发送脚本块,而 RegisterStartupScript() 在 Web 窗体的结尾处(在 </form> 标识之前)发送脚本块。

    为什么会有两种不同的方法来发送客户端脚本?要更好地了解这一点,我们必须首先了解,客户端脚本可以分为两类:一类是在加载页面后立即运行的代码,一类是在发生某些客户端事件时才运行的代码。前者的常见示例是将焦点设置到文本框的客户端代码。例如,当您访问 Google 时,在页面加载后就会执行一小段客户端代码,以自动将焦点设置到搜索文本框。

    以下是后一类代码(为响应客户端事件而运行的代码)的示例。具体而言,在该示例中,单击按钮时将显示一个弹出式对话框:

    <html>
      <body>
        <form>
          <script language="JavaScript">
          <!--
            function displayPopup() {
                alert("Hello, world.");
            }
          // -->
          </script>
    
          <input type="button" value="Click Me!" onclick="displayPopup()" />
        </form>
      </body>
    </html>
    

    在这段代码中,<input> 标记中的 onclick="displayPopup()" 用于指明在单击按钮时,JavaScript 函数 displayPopup() 应该运行。

    RegisterStartupScript() 方法可用于添加要在加载页面后运行的脚本块。通过这种方法添加的脚本块位于 Web 窗体的结尾处,因为必须在脚本运行前定义脚本要修改的 HTML 元素。也就是说,如果您要使用客户端脚本将焦点设置到文本框,必须确保文本框的 HTML 标记位于设置该文本框的焦点的脚本之前。例如,下面的 HTML 将显示一个文本框,并将焦点设置到该文本框:

    <input type="text" id="myTextBox" />
    
    <script language="JavaScript">
    <!--
       document.getElementById("myTextBox").focus();
    // -->
    </script>
    

    相反,以下 HTML 不会将焦点设置到文本框,因为文本框是在脚本块“之后”定义的:

    <script language="JavaScript">
    <!--
       document.getElementById("myTextBox").focus();
    // -->
    </script>
    
    <input type="text" id="myTextBox" />
    

    因此,RegisterStartupScript() 方法将 <script> 块置于 Web 窗体的结尾处,以保证在执行客户端脚本之前已声明 Web 窗体中的所有 HTML 元素。

    RegisterClientScriptBlock() 方法用于为响应客户端事件而执行的脚本代码。通过此方法发送的脚本块位于 Web 页面的开始处,因为这种方法不要求将脚本块置于所有 HTML 元素之后。

    探讨 IsStartupScriptRegistered() 和 IsClientScriptBlockRegistered()

    RegisterStartupScript()RegisterClientScriptBlock() 方法之外,Page 类还包含两个在发送客户端脚本时常用的辅助方法:

    • IsStartupScriptRegistered(key)
    • IsClientScriptBlockRegistered(key)

    如上所述,在使用 RegisterStartupScript()RegisterClientScriptBlock() 插入客户端脚本块时,提供了一个唯一标识脚本块的关键字。这两个方法都接受一个输入(字符串 key),并返回一个布尔值,以指示带有指定关键字的脚本块是否已添加到页面中。具体地说,如果带有特定 key 的脚本块已经注册,这些方法将返回 True,否则将返回 False。

    要了解如何使用这两个方法,可以看一看 ASP.NET 验证 Web 控件,如 RequiredFieldValidator、RegularExpressionValidator 等等。这些控件都会用到一个常用的验证 JavaScript 文件 (WebValidation.js),该文件位于 ASP.NET Web 应用程序的 aspnet_client/system_web/版本号 目录中。因此,所有这些控件都会发送相同的脚本块,这个脚本块将调用在 WebValidation.js 文件中定义的相应的 JavaScript 函数,以启动客户端的验证过程。要完成这个过程,这些控件会使用 Page 类的 RegisterClientScriptBlock() 方法,并使用关键字 ValidatorIncludeScript

    接下来要考虑的是,如果一个 ASP.NET Web 页面中包含多个验证 Web 控件,会出现什么情况呢?所有这些 Web 控件都要使用相同的关键字发送相同的脚本块。如果使用这个关键字调用两次 RegisterClientScriptBlock()RegisterStartupScript() 方法,则第二次调用会被认为是复制脚本块而被忽略。因此,即使一个 Web 页面上有多个验证控件,也只是发送一个公共脚本块的实例。但是,请注意,除第一个控件之外的其他所有验证 Web 控件都会构建要发送的公共客户端脚本,而这只是在浪费时间。

    这时就应该使用 IsClientScriptBlock()IsStartupScript() 方法。这样一来,验证 Web 控件就不会先花时间构建要发送的客户端代码,而是先检查是否已经存在使用关键字 ValidatorIncludeScript 注册的脚本。如果存在,控件就会放弃构建客户端脚本块,因为脚本块已经由页面上的其他验证控件构建了。

    因此,每次构建客户端脚本时,应该首先调用 IsClientScriptBlock()IsStartupScript() 方法,以确定是否需要生成客户端脚本。在下面一节,我们将看到一些示例,在这些示例中,IsClientScriptBlock()IsStartupScript() 方法先后与 RegisterClientScriptBlock()RegisterStartupScript() 方法结合使用。

    从 ASP.NET 服务器控件发送客户端脚本块

    请记住,RegisterStartupScript()RegisterClientScriptBlock() 方法是 System.Web.UI.Page 类的方法。幸运的是,可以容易地从 ASP.NET 服务器控件调用这两个方法,因为 System.Web.UI.Control 类(所有 ASP.NET 服务器控件都直接或间接地从这个类导出)有一个包含对 Page 实例的引用的 Page 属性,而这个 Page 实例包含服务器控件。因此,要从 ASP.NET 服务器控件添加客户端脚本块,您只需使用下面的语法:

    this.Page.RegisterClientScriptBlock(key, script);

    通常,添加客户端脚本块这个任务会使用 OnPreRender() 方法来处理,这个方法在控件生命周期的预呈现阶段执行。

    让我们创建一个只显示客户端弹出式对话框的 ASP.NET 服务器控件。此示例将说明构建一个发送客户端脚本的控件是很容易的。

    首先,在 Microsoft® Visual Studio® .NET 中创建一个新的 Web Control Library(Web 控件库)项目。这将创建一个只有一个类的新项目,这个类从 System.Web.UI.WebControls.WebControl 导出。但是,我们希望这个类从 System.Web.UI.Control 类导出。为什么呢?因为 WebControl 类用于支持显示为 HTML 元素的服务器控件,而 Control 类则用于不会显示为 HTML 元素的服务器控件。

    大多数内置的 ASP.NET 服务器控件都会发送一个 HTML 元素。例如,TextBox Web 控件发送一个 <input> 元素,其类型属性设置为 text;DataGrid Web 控件发送一个 <table> 元素,为每条要显示的记录发送 <tr> 元素,为每个字段发送 <td> 列。但是,不是所有的控件都需要发送 HTML 元素。例如,Literal 控件只是按原样输出它的 Text 属性,而不将这个属性放在 HTML 元素中。同样,Repeater 也不将其输出放在 HTML 元素中。那些显示为 HTML 元素的服务器控件,如 TextBox、Button、DataGrid 等等,是从 System.Web.UI.WebControls.WebControl 类导出的,而那些产生 HTML 元素的控件,如 Literal、Repeater 等,是从 System.Web.UI.Control 类导出的。

    既然我们要创建的服务器控件不可见(它只是发送一个显示弹出式控件的客户端脚本块),这个控件最好从 System.Web.UI.Control 导出,而不是从 System.Web.UI.WebControls.WebControl 导出。

    这个控件只需要两个属性:

    • PopupMessage - 表示要在弹出式对话框中显示的消息的字符串。
    • Enabled - 表示是否启用控件的布尔值。如果启用控件,则显示弹出式对话框,否则不显示。(必须添加一个 Enabled 属性,是因为导出该控件的 Control 类不包括 Enabled 属性,此属性只是隐含地由那些从 WebControl 导出的控件使用。)

    除了这两种属性之外,我们需要覆盖 OnPreRender() 方法。在这里,我们需要调用 RegisterStartupScript(),并传递控件唯一的关键字和恰当的客户端脚本以显示弹出式对话框。这个类的完整代码如下所示:

    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    
    namespace ClientSideScript
    {
       /// <summary>
       /// WebCustomControl1 的摘要描述。
       /// </summary>
       [DefaultProperty("Text"),
          ToolboxData("<{0}吐舌笑脸opupGreeting runat=server></{0}吐舌笑脸opupGreeting>")]
       public class PopupGreeting : System.Web.UI.Control
       {
          [Bindable(true),
             Category("Appearance"),
             DefaultValue("")]
          public string PopupMessage
          {
             get
             {
                // 检查 ViewState 中是否存在该项目
                object popupMessage = this.ViewState["PopupMessage"];
                if (popupMessage != null)
                   return this.ViewState["PopupMessage"].ToString();
                else
                   return "Welcome to my Web site!";
             }
    
             set
             {
                // 指定 ViewState 变量
                ViewState["PopupMessage"] = value;
             }
          }
    
          [Bindable(true),
          Category("Appearance"),
          DefaultValue("")]
          public bool Enabled
          {
             get
             {
                // 检查 ViewState 中是否存在该项目
                object enabled = this.ViewState["Enabled"];
                if (enabled != null)
                   return (bool) this.ViewState["Enabled"];
                else
                   return true;
             }
    
             set
             {
                // 指定 ViewState 变量
                ViewState["Enabled"] = value;
             }
          }
    
    
          protected override void OnPreRender(EventArgs e)
          {
             base.OnPreRender电子邮件;
    
    string scriptKey = "intoPopupMessage:" + this.UniqueID;
    
             if (!Page.IsStartupScriptRegistered(scriptKey) && this.Enabled &&
                          !Page.IsPostBack)
             {
                string scriptBlock = 
                   @"<script language=""JavaScript"">
                   <!--
                      alert(""%%POPUP_MESSAGE%%"");
                   // -->
                   </script>";
                scriptBlock = scriptBlock.Replace("%%POPUP_MESSAGE%%", this.PopupMessage);
    
                Page.RegisterStartupScript(scriptKey, scriptBlock);
             }
          }
       }
    }
    

    请记住下面两件事:首先,EnabledPopupMessage 属性保存在 ViewState 中,这样在回传时这些值可以始终保持一致; 其次,在 OnPreRender() 方法中,用于脚本块的关键字是文本 intoPopupMessage: 加上控件的 UniqueID 属性。如果使用一个硬编码的关键字,则当页面中有多个控件时,只有第一个控件能够注册其脚本块,因此只显示一个弹出式对话框。通过在脚本块关键字中使用 UniqueID,就能保证该控件的每个实例都能获取其脚本块。

    在注册脚本块之前,代码首先检查三个条件:

    1. 没有使用同一关键字注册的脚本。这当然是不可能的,因为每个控件实例都应该有一个 UniqueID 属性值。但是,不妨先练习使用 IsStartupScriptRegistered() 方法,然后再花时间创建和注册启动脚本。
    2. 控件的 Enabled 属性为 True。
    3. 页面没有被回传。这段代码只允许弹出式对话框在第一次加载页面时显示,而不是在每次回传页面时都显示。我们还可以增添更为灵活的功能,即为该控件添加一个布尔属性,以允许用户指定是否在回传时也生成弹出式对话框。

    如果满足这三个条件,则脚本被指定,并且 PopupMessage 属性值被插入到脚本中适当的位置。最后,调用 Page 属性的 RegisterStartupScript() 方法,传入关键字及脚本代码。

    PopupGreeting 代码可以从本文结尾处提供的下载中获得。该下载包括名为 ClientSideControlsAndTester 的 Visual Studio .NET 解决方案,其中包含两个项目:

    • ClientSideControls,包含 PopupGreeting 服务器控件
    • ClientSideTester,包括一个为测试 ClientSideControls 而设计的 ASP.NET Web 应用程序

    ClientSideControls 项目编译后的程序集名为 ClientSideControls.dll。要在您自己的 ASP.NET Web 应用程序中使用 PopupGreeting 服务器控件,请将 ClientSideControls.dll 文件添加到您的 Web 应用程序的引用中。然后,在设计器中,右键单击 Toolbox(工具箱)并选择“Add/Remove Items . . .”(添加/删除项),再次选择 ClientSideControls.dll 文件。这样就向 Toolbox(工具箱)中添加了名为 PopupGreeting 的新项。然后,您可以从 Toolbox(工具箱)将该控件拖到设计器中。

    图 2 显示了 PopupGreeting 控件添加到 Toolbox(工具箱)并添加到设计器后,Visual Studio .NET 的屏幕快照。Toolbox(工具箱)中的 PopupGreeting 控件用红色线圈出,设计器中的 PopupGreeting 输出用蓝色线圈出,在屏幕快照右侧的“Properties”(属性)窗格中可以查看 PopupGreeting 的属性。

    图 2:PopupGreeting 服务器控件已添加到 ASP.NET Web 窗体页面

    发送 ASP.NET 服务器 Web 控件的 HTML 属性

    如上所述,有两种方法可以通过服务器控件发送客户端脚本:

    • 通过使用客户端脚本块
    • 通过 HTML 元素属性

    在上一节中,我们探讨了如何使用 Page 类的 RegisterStartupScript()RegisterClientScriptBlock() 方法向 ASP.NET Web 页面添加客户端脚本块。在最后这一节,我们了解如何将 HTML 元素属性添加到服务器控件的 HTML 元素。

    在开始之前,请注意这种方法通常只适用于从 System.Web.UI.WebControls.WebControl 类导出的服务器控件,因为从这个类导出的控件会发送某些 HTML 元素。不发送 HTML 元素的服务器控件(如上一节中的 PopupGreeting 服务器控件),则不必写出 HTML 元素属性,因为这些控件运行时不会写出 HTML 元素。

    WebControl 类包含一个将 HTML 元素属性添加到由 Web 控件发出的 HTML 元素的方法。该方法称为 AddAttributesToRender(),它只有一个输入参数,即 HtmlTextWriter 的实例。要向 Web 控件添加 HTML 属性,您可以使用 HtmlTextWriter 的以下两个方法之一:

    • AddAttribute()
    • AddStyleAttribute()

    AddAttribute() 方法用于将 titleclassstyleonclick 等 HTML 属性添加到 HTML 元素。AddStyleAttribute() 用于将样式设置添加到 HTML 元素,如 background-colorcolorfont-size 等。

    AddAttribute() 有几个重载窗体,但在代码中,我们将使用以下窗体:AddAttribute(HtmlTextWriterAttribute, value)。第一个参数,即 HtmlTextWriterAttribute,应该是 HtmlTextWriterAttribute 枚举的成员。该枚举包含像 AlignBgcolorClassOnclick 等项。您可以在 .NET Framework Class Library,HtmlTextWriterAttribute Enumeration 中找到完整的列表。value 输入参数用于指定分配给特定 HTML 属性的值。最后,如果您想添加一个 HtmlTextWriterAttribute 枚举中未定义的 HTML 属性,可以使用 AddAttribute() 方法的替代形式 AddAttribute(attributeName, value),其中的 attributeNamevalue 均为字符串。

    为了运用该信息,我们创建一个作为确认按钮的服务器 Web 控件。确认按钮是一种提交按钮,当用户单击此按钮时,将显示一个弹出式对话框,询问用户是否确定要继续操作。用户可以单击“取消”,不提交窗体。此项功能对用于删除信息的按钮特别有用,因为最终用户(或网站管理员)可能会在无意中单击鼠标删除数据库中的条目,如果没有机会取消,将是非常令人烦恼的事。

    为了减少工作量,我们从 System.Web.UI.WebControls.Button 类中导出 ConfirmButton Web 控件,因为这个类本身已完成了涉及呈现提交按钮的所有繁重工作。在导出的类中,我们只需添加一个属性,这样用户可以指定确认消息,然后覆盖按钮的 AddAttributesToRender() 方法,并添加一个属性以处理客户端事件 onclick

    首先,在 Visual Studio .NET 中创建一个新的 Web Control Library(Web 控件库)项目,或者在 ClientSideControls 项目中添加一个新的 Web Custom Control(Web 自定义控件)。ConfirmButton 类的完整源代码如下所示:

    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    
    namespace ClientSideControls
    {
       /// <summary>
       /// ConfirmButton 的摘要描述。
       /// </summary>
       [DefaultProperty("Text"), 
          ToolboxData("<{0}:ConfirmButton runat=server></{0}:ConfirmButton>")]
       public class ConfirmButton : Button
       {
          [Bindable(true), 
             Category("Appearance"), 
             DefaultValue("")] 
          public string PopupMessage
          {
             get
             {
                // 检查 ViewState 中是否存在该项目
                object popupMessage = this.ViewState["PopupMessage"];
                if (popupMessage != null)
                   return this.ViewState["PopupMessage"].ToString();
                else
                   return "Are you sure you want to continue?";
             }
    
             set
             {
                // 指定 ViewState 变量
                ViewState["PopupMessage"] = value;
             }
          }
    
    
          protected override void AddAttributesToRender(HtmlTextWriter writer)
          {
             base.AddAttributesToRender(writer);
    
             string script = @"return confirm(""%%POPUP_MESSAGE%%"");";
             script = script.Replace("%%POPUP_MESSAGE%%", 
                this.PopupMessage.Replace("\"", "\\\""));
    
             writer.AddAttribute(HtmlTextWriterAttribute.Onclick, script);
          }
       }
    }
    

    首先要注意的是,ConfirmButton 类是从 Button 类导出的。由于 Button 类已包含 Button Web 控件使用的所有属性和方法,因此我们所做的只是添加属性和方法,以在用户单击按钮时显示一个确认对话框。现在我们需要一个属性,即 PopupMessage,它是要在确认弹出式对话框中显示的消息。默认情况下,这条消息是“Are you sure you want to continue?”(您确定要继续吗?)如果使用 ConfirmButton 来确认删除,可能需要将该消息更改为“This action will permanently delete the selected item. Are you sure you want to do this?”(此操作将永久删除所选项。您确定要继续吗?)

    我们只需覆盖一个方法,即 AddAttributesToRender()。在此方法中,我们只要构建当触发 <input> 元素的 onclick 事件时要执行的客户端 JavaScript,然后通过传入的 HtmlTextWriter 对象的 AddAttribute() 方法添加这段 JavaScript。关于这个方法,有一点要注意,必须将 PopupMessage 属性值中的所有双引号实例替换为转义双引号(即 \")。另外还要注意,默认情况下,AddAttribute() 会对第二个参数中的字符进行 HTML 编码。也就是说,ASP.NET Web 页面中如果包含 PopupMessage 属性被设置为“Do you want to continue?”(要继续吗?)的 ConfirmButton,该页面将发送以下 HTML 标记:

    <input type="submit" name="ConfirmButton1" 
    value="Click Me!" id="ConfirmButton1" onclick="return confirm
    (&quot;Do you want to continue?&quot眨眼笑脸;" />
    

    如果您不熟悉 JavaScript 的 confirm(string) 函数,那么请您注意,该函数只接受一个字符串参数,并显示一个带有特定字符串的模式对话框。该对话框中包含两个按钮:“确定”和“取消”。如果单击“确定”,confirm() 函数返回 True,否则返回 False。请注意,onclick 事件将返回 confirm() 函数调用的结果。当通过单击提交按钮来提交表单时,如果提交按钮的 onclick 事件返回 False,则表单未被提交。因此,只有在用户确认后,可以使用 confirm() 函数提交表单。有关 confirm() 的详细信息,请参阅 ASP Warrior 网站中的 Javascript Confirm Form Submission

    图 3:操作中的 ConfirmButton

    ConfirmButton 在按钮的 onclick 事件处理程序中使用了内嵌的 JavaScript,还可以在 ConfirmButton 的 OnPreRender() 方法的客户端脚本块中创建一个函数,然后调整 onclick 属性以调用该函数。

    小结

    在本文中,我们探讨了两种通过 ASP.NET 服务器控件插入客户端脚本的方法。第一种方法是使用 Page 类的 RegisterStartupScript()RegisterClientScriptBlock() 方法插入客户端脚本块。第二种方法是向 HTML 元素的属性添加客户端脚本。后者通过覆盖 Web 服务器控件的 AddAttributesToRender() 方法,并使用 HtmlTextWriterAddAttribute() 方法来完成。

    我们还在文中介绍了两个简单的服务器控件,它们都利用了客户端脚本来改进其功能。PopupGreeting 控件在页面首次加载时显示一个模式弹出式对话框,ConfirmButton Web 控件在用户单击按钮提交表单时,提示用户进行确认。

    您可以在自己的服务器控件中插入客户端脚本,这将显著改善用户体验。本文提供的两个服务器控件相对比较简单,在可用性和独创性上没有什么突出之处。MetaBuilders.com 中展示了很多利用从 ASP.NET 服务器控件中插入客户端脚本而实现的功能,这些功能会给您留下深刻印象。在 MetaBuilders.com,您可以找到一些服务器控件,它们有的可以自动将焦点添加到文本框,有的可以在两个下拉列表之间传递条目,有的可以向下拉列表中添加或删除条目,还有的可以在一系列下拉列表中显示父子关系的数据,等等。最大的好处是,这些控件是免费的,并包括完整的源代码。

    祝大家编程快乐!

    作者简介

    Scott Mitchell 著有五本关于 ASP/ASP.NET 的书籍,是 4GuysFromRolla.com 网站的创始人,过去五年来一直从事 Microsoft Web 技术方面的研究。Scott 是 ASP 和 ASP.NET 社区非常活跃的一名成员,十分热爱 ASP 和 ASP.NET 技术,并非常愿意帮助其他人了解这些令人振奋的技术。有关 DataGrid、DataList 和 Repeater 控件的详细信息,请参阅 Scott 的著作《ASP.NET Data Web Controls Kick Start》(ISBN 为 0672325012)。

    推荐链接:

  • 百万富婆为促儿上进回乡务农 儿子成才母亲病逝

    http://www.sina.com.cn 2004年09月12日22:54 东亚经贸新闻

      本报吉林讯(东亚记者 冯丽媛)2004年9月9日,王青(化名)在弥留之际,满意地看了儿子最后一眼,不舍地离开了人世……

      这位伟大的母亲,为了让儿子成材,毅然放弃了蒸蒸日上的生意,放弃了城里安逸的生活,变卖家财与儿子一起来到农村。而当儿子如她所愿大学毕业后,她来不及与儿子分享这份快乐,便因胃癌早早地离开了人士,这一年,她刚刚49岁。

      为儿成材 “富婆”携子下乡

      1980年5月初,王青以3500元钱的价格将吉林市的一个美发店兑下来后,便开始了自己的创业历程,在1985年和丈夫离婚后,她把所有的精力都放在了生意上,根本没有时间照顾儿子乐乐。她觉得欠儿子太多了,因此,只要是乐乐的要求,王青总是尽量满足。

      1990年8月,11岁的乐乐已经升入小学4年级,班里有个同学的父亲是某局局长,每天上下学都有专车接送,令乐乐羡慕不已。为了满足乐乐的愿望,王青就找到一个出租车司机,每天早晚接送乐乐。从此,乐乐成了班里第二个每天有车接送的孩子。

      然而这一切的骄纵,反而使乐乐成了一个满是恶习的坏孩子,他经常与同学打架,有一次还动手打了老师。

      王青越来越意识到问题的严重性。为了拯救乐乐,王青终于做出一个痛苦的决定,放弃蒸蒸日上的生意,放弃城里安逸的生活,携子下乡,用贫困的生活方式来锻炼儿子。

      伟大母亲换得爱子光明前途

      1995年3月20日,王青在变卖家财后,带着几百万元的存折,重新回到阔别16年的永吉县老家。她在村里承租了5亩山地,然后将乐乐送到了离家8里地的中学读书。而享乐惯了的乐乐,几次吃饭时突然将饭碗砸在墙上,抱怨母亲不再给他以前那样无忧无虑的生活。

      一次,乐乐从王青兜里拿了家里仅有的18元钱,趁午休时间去饭店点了一道最爱吃的锅煲肉……等乐乐回家后,王青什么也没说,端着一碗米饭泡开水坐在地中间艰难地咽着,泪水落在饭碗里。这个时候,王青也想从自己的几百万存折中取出一些钱来,但她又怕乐乐看出来,最后彻底打消了这一念头。

      随着时间的推移,王青的操劳终于使乐乐变得懂事了。在一个除夕之夜,王青给乐乐做了一条鱼和一碗红烧肉,乐乐夹起一块肉放在王青的碗内:“妈,你也吃一块吧!”听到这句话,王青的泪水夺眶而出。当晚,母子俩紧挨着坐在炕头上观看春节联欢晚会,虽然谁也没说话,但王青感到与儿子的心贴近了。

      1996年,王青多承包了几亩地,王青又有了新的积蓄6500元,乐乐当即向王青要了100元钱,王青的心猛地一沉,难道几年来的心血都付之东流了吗?整整一天,王青的心情都非常沉重。当天晚上,乐乐放学时高兴地跑到王青身边,将一件新衣服硬是套在王青身上:“妈妈,这几年你连一件新衣服都没买,今天我给你买了一件,剩下20元钱我给你买了几盒治胃疼的药。”看到这一切,王青紧紧地抱住乐乐,久久不肯松手。

      2000年7月,乐乐终于如愿考上了大学。拿着录取通知书,王青像个孩子似的蹲在地上放声大哭起来,把5年来自己所有的委屈都哭了出来,为了乐乐能成材,她实在放弃了太多太多。但令她欣慰的是,她放弃的一切,终于换来了儿子光明的前途。

      临终说出真相母爱感动爱子

      2003年5月,乐乐在写给***信中说快要毕业了,而且已经联系好了工作单位。此时,王青被确诊为胃癌晚期,已经没有治疗的价值了。

      2003年7月,乐乐结束了3年的大学生活,回到了妈妈身边。当乐乐得知妈妈已是胃癌晚期时,失声痛哭。第二天,乐乐强行将妈妈送进了医院,但每天昂贵的治疗费让乐乐犯愁。看着乐乐每天跑前跑后的,王青决定把所有的事情都告诉儿子。

      那天,她把5个存折都交到了乐乐手中,将变卖家财,带他来到农村的前前后后和盘而出。

      王青满意地看着儿子说,“妈妈虽然失去了很多,付出了很多,但我赢得了一个品学兼优的好儿子。妈妈觉得值得。”听完王青说出真相,乐乐一下跪倒在床头,一声“妈妈”,叫得其他病友泪水纷纷而下。

      2004年9月9日午夜,王青最后看了儿子一眼后,不舍地离开了这个世界……

  • WINDOWS2000命令大全(1)--(5)

    accwiz.exe > Accessibility Wizard for walking you through setting up your machine for your mobility needs. 辅助工具向导

    acsetups.exe > ACS setup DCOM server executable

    actmovie.exe > Direct Show setup tool 直接显示安装工具

    append.exe > Allows programs to open data in specified directories as if they were in the current directory. 允许程序打开制定目录中的数据

    arp.exe > NETWORK Display and modify IP - Hardware addresses 显示和更改计算机的IP与硬件物理地址的对应列表

    at.exe > AT is a scheduling utility also included with UNIX 计划运行任务

    atmadm.exe > Displays statistics for ATM call manager. ATM调用管理器统计

    attrib.exe > Display and modify attributes for files and folders 显示和更改文件和文件夹属性

    autochk.exe > Used to check and repair Windows File Systems 检测修复文件系统

    autoconv.exe > Automates the file system conversion during reboots 在启动过程中自动转化系统

    autofmt.exe > Automates the file format process during reboots 在启动过程中格式化进程

    autolfn.exe > Used for formatting long file names 使用长文件名格式

    bootok.exe > Boot acceptance application for registry

    bootvrfy.exe > Bootvrfy.exe, a program included in Windows 2000 that notifies the system that startup was successful. Bootvrfy.exe can be run on a local or remote computer. 通报启动成功
    cacls.exe > Displays or modifies access control lists (ACLs) of files. 显示和编辑ACL

    calc.exe > Windows Calculators 计算器

    cdplayer.exe > Windows CD Player CD播放器

    change.exe > Change { User | Port | Logon } 与终端服务器相关的查询

    charmap.exe > Character Map 字符映射表

    chglogon.exe > Same as using "Change Logon" 启动或停用会话记录

    chgport.exe > Same as using "Change Port" 改变端口(终端服务)

    chgusr.exe > Same as using "Change User" 改变用户(终端服务)

    chkdsk.exe > Check the hard disk for errors similar to Scandisk 3 Stages must specify a Drive Letter 磁盘检测程序

    chkntfs.exe > Same as using chkdsk but for NTFS NTFS磁盘检测程序

    cidaemon.exe > Component of Ci Filer Service 组成Ci文档服务

    cipher.exe > Displays or alters the encryption of directories [files] on NTFS partitions. 在NTFS上显示或改变加密的文件或目录

    cisvc.exe > Content Index -- It`s the content indexing service for I 索引内容

    ckcnv.exe > Cookie Convertor 变换Cookie

    cleanmgr.exe > Disk Cleanup, popular with Windows 98 磁盘清理

    cliconfg.exe > SQL Server Client Network Utility SQL客户网络工具

    clipbrd.exe > Clipboard viewer for Local will allow you to connect to other clipboards 剪贴簿查看器

    clipsrv.exe > Start the clipboard Server 运行Clipboard服务

    clspack.exe > CLSPACK used to create a file listing of system packages 建立系统文件列表清单

    cluster.exe > Display a cluster in a domain 显示域的集群

    _cmd_.exe > Famous command prompt 没什么好说的!

    cmdl32.exe > Connection Manager Auto-Download 自动下载连接管理

    cmmgr32.exe > Connection Manager 连接管理器

    cmmon32.exe > Connection Manager Monitor 连接管理器监视

    cmstp.exe > Connection Manager Profile Manager 连接管理器配置文件安装程序

    comclust.exe > about cluster server 集群

    comp.exe > ComClust Add, Remove, or Join a cluster. 比较两个文件和文件集的内容*

    compact.exe > Displays or alters the compression of files on NTFS partitions. 显示或改变NTFS分区上文件的压缩状态

    conime.exe > Console IME IME控制台

    control.exe > Starts the control panel 控制面板

    convert.exe > Convert File System to NTFS 转换文件系统到NTFS

    convlog.exe > Converts MS IIS log files 转换IIS日志文件格式到NCSA格式

    cprofile.exe > Copy profiles 转换显示模式

    cscript.exe > MS Windows Scripts Host Version 5.1 较本宿主版本

    csrss.exe > Client Server Runtime Process 客户服务器Runtime进程

    csvde.exe > Comma Separated Variable Import/Export Utility 日至格式转换程序

    WINDOWS2000命令大全(2)


    dbgtrace.exe > 和Terminal Server相关

    dcomcnfg.exe > Display the current DCOM configuration. DCOM配置属性

    dcphelp.exe > ?

    dcpromo.exe > Promote a domain controller to ADSI AD安装向导

    ddeshare.exe > Display DDE shares on local or remote computer DDE共享

    ddmprxy.exe >

    debug.exe > Runs Debug, a program testing and editing tool. 就是DEBUG啦!

    dfrgfat.exe > Defrag FAT file system FAT分区磁盘碎片整理程序

    dfrgntfs.exe > Defrag NTFS file system NTFS分区磁盘碎片整理程序

    dfs_cmd_.exe > configures a Dfs tree 配置一个DFS树

    dfsinit.exe > Distributed File System Initialization 分布式文件系统初始化

    dfssvc.exe > Distributed File System Server 分布式文件系统服务器

    diantz.exe > MS Cabinet Maker 制作CAB文件

    diskperf.exe > Starts physical Disk Performance counters 磁盘性能计数器

    dllhost.exe > dllhost is used on all versions of Windows 2000. dllhost is the hedost process for all COM+ applications. 所有COM+应用软件的主进程

    dllhst3g.exe >

    dmadmin.exe > Disk Manager Service 磁盘管理服务

    dmremote.exe > Part of disk management 磁盘管理服务的一部分

    dns.exe > DNS Applications DNS

    doskey.exe > recalls Windows command lines and creates macros 命令行创建宏

    dosx.exe > DOS Extender DOS扩展

    dplaysvr.exe > Direct Play Helper 直接运行帮助

    drwatson.exe > Dr Watson for 2000 Fault Detector 华生医生错误检测

    drwtsn32.exe > Dr Watson for 2000 viewer and configuration manager 华生医生显示和配置管理

    dtcsetup.exe > Installs MDTC

    dvdplay.exe > Windows 2000 DVD player DVD播放

    dxdiag.exe > Direct-X Diagnostics Direct-X诊断工具

    edlin.exe > line-oriented text editor. 命令行的文本编辑器(历史悠久啊!)
    edlin.exe > line-oriented text editor. 命令行的文本编辑器(历史悠久啊!)

    esentutl.exe > MS Database Utility MS数据库工具

    eudcedit.exe > Private character editor Ture Type造字程序

    eventvwr.exe > Windows 2000 Event Viewer 事件查看器
    evnt_cmd_.exe > Event to trap translator; Configuration tool

    evntwin.exe > Event to trap translator setup

    exe2bin.exe > Converts EXE to binary format 转换EXE文件到二进制

    expand.exe > Expand Files that have been compressed 解压缩

    extrac32.exe > CAB File extraction utility 解CAB工具

    fastopen.exe > Fastopen tracks the location of files on a hard disk and stores the information in memory for fast access. 快速访问在内存中的硬盘文件

    faxcover.exe > Fax Cover page editor 传真封面编辑

    faxqueue.exe > Display Fax Queue 显示传真队列

    faxsend.exe > Fax Wizard for sending faxes 发送传真向导

    faxsvc.exe > Starts fax server 启动传真服务

    fc.exe > Compares two files or sets of files and their differences 比较两个文件的不同

    find.exe > Searches for a text string in file or files 查找文件中的文本行

    findstr.exe > Searches for strings in files 查找文件中的行

    finger.exe > Fingers a user and displays statistics on that user Finger一个用户并显示出统计结果

    fixmapi.exe > Fix mapi files 修复MAPI文件

    flattemp.exe > Enable or disable temporally directories 允许或者禁用临时文件目录

    fontview.exe > Display fonts in a font file 显示字体文件中的字体

    forcedos.exe > Forces a file to start in dos mode. 强制文件在DOS模式下运行

    freecell.exe > Popular Windows Game 空当接龙

    ftp.exe > File Transfer Protocol used to transfer files over a network connection 就是FTP了

    gdi.exe > Graphic Device Interface 图形界面驱动

    grovel.exe >

    grpconv.exe > Program Manager Group Convertor 转换程序管理员组

    WINDOWS2000命令大全(3)


    help.exe > displays help for Windows 2000 commands 显示帮助

    hostname.exe > Display hostname for machine. 显示机器的Hostname

    ie4uinit.exe > IE5 User Install tool IE5用户安装工具

    ieshwiz.exe > Customize folder wizard 自定义文件夹向导

    iexpress.exe > Create and setup packages for install 穿件安装包

    iisreset.exe > Restart IIS Admin Service 重启IIS服务

    internat.exe > Keyboard Language Indicator Applet 键盘语言指示器

    ipconfig.exe > Windows 2000 IP configuration. 察看IP配置

    ipsecmon.exe > IP Security Monitor IP安全监视器

    ipxroute.exe > IPX Routing and Source Routing Control Program IPX路由和源路由控制程序

    irftp.exe > Setup FTP for wireless communication 无线连接

    ismserv.exe > Intersite messaging Service 安装或者删除Service Control Manager中的服务

    jdbgmgr.exe > Microsoft debugger for java 4 Java4的调试器

    jetconv.exe > Convert a Jet Engine Database 转换Jet Engine数据库

    jetpack.exe > Compact Jet Database. 压缩Jet数据库

    jview.exe > Command-line loader for Java Java的命令行装载者

    krnl386.exe > Core Component for Windows 2000 2000的核心组件

    label.exe > Change label for drives 改变驱动器的卷标

    lcwiz.exe > License Compliance Wizard for local or remote systems. 许可证符合向导

    ldifde.exe > LDIF cmd line manager LDIF目录交换命令行管理

    licmgr.exe > Terminal Server License Manager 终端服务许可协议管理

    lights.exe > display connection status lights 显示连接状况

    llsmgr.exe > Windows 2000 License Manager 2000许可协议管理

    llssrv.exe > Start the license Server 启动许可协议服务器

    lnkstub.exe >

    locator.exe > RPC Locator 远程定位

    lodctr.exe > Load perfmon counters 调用性能计数

    logoff.exe > Log current user off. 注销用户

    lpq.exe > Displays status of a remote LPD queue 显示远端的LPD打印队列的状态,显示被送到基于Unix的服务器的打印任务

    lpr.exe > Send a print job to a network printer. 重定向打印任务到网络中的打印机。通常用于Unix客户打印机将打印任务发送给连接了打印设备的NT的打印机服务器。

    lsass.exe > LSA Executable and Server DLL 运行LSA和Server的DLL

    lserver.exe > Specifies the new DNS domain for the default server 指定默认Server新的DNS域

    macfile.exe > Used for managing MACFILES 管理MACFILES

    magnify.exe > Used to magnify the current screen 放大镜

    makecab.exe > MS Cabinet Maker 制作CAB文件

    mdm.exe > Machine Debug Manager 机器调试管理

    mem.exe > Display current Memory stats 显示内存状态

    migpwd.exe > Migrate passwords. 迁移密码

    mmc.exe > Microsoft Management Console 控制台

    mnmsrvc.exe > Netmeeting Remote Desktop Sharing NetMeeting远程桌面共享

    mobsync.exe > Manage Synchronization. 同步目录管理器

    mountvol.exe > Creates, deletes, or lists a volume mount point. 创建、删除或列出卷的装入点。

    mplay32.exe > MS Media Player 媒体播放器

    mpnotify.exe > Multiple Provider Notification application 多提供者通知应用程序

    mq1sync.exe >

    mqbkup.exe > MS Message Queue Backup and Restore Utility 信息队列备份和恢复工具

    mqexchng.exe > MSMQ Exchange Connector Setup 信息队列交换连接设置

    mqmig.exe > MSMQ Migration Utility 信息队列迁移工具

    mqsvc.exe > ?

    mrinfo.exe > Multicast routing using SNMP 使用SNMP多点传送路由

    mscdexnt.exe > Installs MSCD (MS CD Extensions) 安装MSCD

    msdtc.exe > Dynamic Transaction Controller Console 动态事务处理控制台

    msg.exe > Send a message to a user local or remote. 发送消息到本地或远程客户

    mshta.exe > HTML Application HOST HTML应用程序主机

    msiexec.exe > Starts Windows Installer Program 开始Windows安装程序mspaint.exe > Microsoft Paint 画板

    msswchx.exe >

    mstask.exe > Task Schedule Program 任务计划表程序

    mstinit.exe > Task scheduler setup 任务计划表安装

    narrator.exe > Program will allow you to have a narrator for reading. Microsoft讲述人

    nbtstat.exe > Displays protocol stats and current TCP/IP connections using NBT 使用 NBT(TCP/IP 上的 NetBIOS)显示协议统计和当前 TCP/IP 连接。

    nddeapir.exe > NDDE API Server side NDDE API服务器端

    net.exe > Net Utility 详细用法看/?

    net1.exe > Net Utility updated version from MS Net的升级版

    netdde.exe > Network DDE will install itself into the background 安装自己到后台

    netsh.exe > Creates a shell for network information 用于配置和监控 Windows 2000 命令行脚本接口。

    netstat.exe > Displays current connections. 显示协议统计和当前的 TCP/IP 网络连接。

    nlsfunc.exe > Loads country-specific information 加载特定国家(地区)的信息。Windows 2000 和 MS-DOS 子系统不使用该命令。接受该命令只是为了与 MS-DOS 文件兼容。

    notepad.exe > Opens Windows 2000 Notepad 记事本

    nslookup.exe > Displays information for DNS 该诊断工具显示来自域名系统 (DNS) 名称服务器的信息。

    ntbackup.exe > Opens the NT Backup Utility 备份和故障修复工具

    ntbooks.exe > Starts Windows Help Utility 帮助

    ntdsutil.exe > Performs DB maintenance of the ADSI 完成ADSI的DB的维护

    ntfrs.exe > NT File Replication Service NT文件复制服务

    ntfrsupg.exe >

    ntkrnlpa.exe > Kernel patch 核心补丁

    ntoskrnl.exe > Core NT Kernel KT的核心

    ntsd.exe >

    ntvdm.exe > Simulates a 16-bit Windows environment 模拟16位Windows环境

    nw16.exe > Netware Redirector NetWare转向器

    nwscript.exe > runs netware scripts 运行Netware脚本

    WINDOWS2000命令大全(4)


    odbcad32.exe > ODBC 32-bit Administrator 32位ODBC管理

    odbcconf.exe > Configure ODBC driver`s and data source`s from command line 命令行配置ODBC驱动和数据源

    os2.exe > An OS/2 Warp Server (os2 /o) OS/2

    os2srv.exe > An OS/2 Warp Server OS/2

    os2ss.exe > An OS/2 Warp Server OS/2

    osk.exe > On Screen Keyboard 屏幕键盘

    packager.exe > Windows 2000 Packager Manager 对象包装程序

    pathping.exe > Combination of Ping and Tracert 包含Ping和Tracert的程序

    pax.exe > is a POSIX program and path names used as arguments must be specified in POSIX format. Use "//C/Users/Default" instead of "C:\USERS\DEFAULT." 启动便携式存档互换 (Pax) 实用程序

    pentnt.exe > Used to check the Pentium for the floating point division error. 检查Pentium的浮点错误

    perfmon.exe > Starts Windows Performance Monitor 性能监视器

    ping.exe > Packet Internet Groper 验证与远程计算机的连接

    posix.exe > Used for backward compatibility with Unix 用于兼容Unix

    print.exe > Cmd line used to print files 打印文本文件或显示打印队列的内容。

    progman.exe > Program manager 程序管理器

    proquota.exe > Profile quota program

    psxss.exe > POSIX Subsystem Application Posix子系统应用程序

    qappsrv.exe > Displays the available application terminal servers on the network
    在网络上显示终端服务器可用的程序

    qprocess.exe > Display information about processes local or remote 在本地或远程显示进程的信息(需终端服务)

    query.exe > Query TERMSERVER user process and sessions 查询进程和对话

    quser.exe > Display information about a user logged on 显示用户登陆的信息(需终端服务)

    qwinsta.exe > Display information about Terminal Sessions. 显示终端服务的信息

    rasadmin.exe > Start the remote access admin service 启动远程访问服务

    rasautou.exe > Creates a RAS connection 建立一个RAS连接

    rasdial.exe > Dial a connection 拨号连接

    rasphone.exe > Starts a RAS connection 运行RAS连接

    rcp.exe > Copies a file from and to a RCP service. 在 Windows 2000 计算机和运行远程外壳端口监控程序 rshd 的系统之间复制文件

    rdpclip.exe > RdpClip allows you to copy and paste files between a terminal session and client console session. 再终端和本地复制和粘贴文件

    recover.exe > Recovers readable information from a bad or defective disk 从坏的或有缺陷的磁盘中恢复可读取的信息。

    redir.exe > Starts the redirector service 运行重定向服务

    regedt32.exe > 32-bit register service 32位注册服务

    regini.exe > modify registry permissions from within a script 用脚本修改注册许可

    register.exe > Register a program so it can have special execution characteristics. 注册包含特殊运行字符的程序

    regsvc.exe >

    regsvr32.exe > Registers and unregister`s dll`s. As to how and where it register`s them I dont know. 注册和反注册DLL

    regtrace.exe > Options to tune debug options for applications failing to dump trace statements
    Trace 设置
    regwiz.exe > Registration Wizard 注册向导

    remrras.exe >

    replace.exe > Replace files 用源目录中的同名文件替换目标目录中的文件。

    reset.exe > Reset an active section 重置活动部分

    rexec.exe > Runs commands on remote hosts running the REXEC service. 在运行 REXEC 服务的远程计算机上运行命令。rexec 命令在执行指定命令前,验证远程计算机上的用户名,只有安装了 TCP/IP 协议后才可以使用该命令。

    risetup.exe > Starts the Remote Installation Service Wizard. 运行远程安装向导服务

    route.exe > display or edit the current routing tables. 控制网络路由表

    routemon.exe > no longer supported 不再支持了!

    router.exe > Router software that runs either on a dedicated DOS or on an OS/2 system. Route软件在 DOS或者是OS/2系统

    rsh.exe > Runs commands on remote hosts running the RSH service 在运行 RSH 服务的远程计算机上运行命令

    rsm.exe > Mounts and configures remote system media 配置远程系统媒体

    rsnotify.exe > Remote storage notification recall 远程存储通知回显

    rsvp.exe > Resource reservation protocol 源预约协议

    runas.exe > RUN a program as another user 允许用户用其他权限运行指定的工具和程序

    rundll32.exe > Launches a 32-bit dll program 启动32位DLL程序

    runonce.exe > Causes a program to run during startup 运行程序再开始菜单中

    rwinsta.exe > Reset the session subsystem hardware and software to known initial values 重置会话子系统硬件和软件到最初的值

    savedump.exe > Does not write to e:\winnt\user.dmp 不写入User.dmp中

    scardsvr.exe > Smart Card resource management server 子能卡资源管理服务器

    schupgr.exe > It will read the schema update files (.ldf files) and upgrade the schema. (part of ADSI) 读取计划更新文件和更新计划

    secedit.exe > Starts Security Editor help 自动安全性配置管理

    services.exe > Controls all the services 控制所有服务

    sethc.exe > Set High Contrast - changes colours and display mode Logoff to set it back to normal 设置高对比

    setreg.exe > Shows the Software Publishing State Key values 显示软件发布的国家语言

    setup.exe > GUI box prompts you to goto control panel to configure system components 安装程序(转到控制面板)

    setver.exe > Set Version for Files 设置 MS-DOS 子系统向程序报告的 MS-DOS 版本号

    sfc.exe > System File Checker test and check system files for integrity 系统文件检查

    sfmprint.exe > Print Services for Macintosh 打印Macintosh服务

    sfmpsexe.exe >

    sfmsvc.exe >

    shadow.exe > Monitor another Terminal Services session. 监控另外一台中端服务器会话

    share.exe > Windows 2000 和 MS-DOS 子系统不使用该命令。接受该命令只是为了与 MS-DOS 文件兼容

    shmgrate.exe >

    shrpubw.exe > Create and Share folders 建立和共享文件夹

    sigverif.exe > File Signature Verification 文件签名验证

    skeys.exe > Serial Keys utility 序列号制作工具

    smlogsvc.exe > Performance Logs and Alerts 性能日志和警报

    smss.exe >

    sndrec32.exe > starts the Windows Sound Recorder 录音机

    sndvol32.exe > Display the current volume information 显示声音控制信息

    snmp.exe > Simple Network Management Protocol used for Network Mangement 简单网络管理协议

    snmptrap.exe > Utility used with SNMP SNMP工具

    sol.exe > Windows Solitaire Game 纸牌

    sort.exe > Compares files and Folders 读取输入、排序数据并将结果写到屏幕、文

  • decode()函數使用技巧
    ·        软件环境:
    1、Windows NT4.0+ORACLE 8.0.4
    2、ORACLE安装路径为:C:\ORANT
    ·        含义解释:
    decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)

    该函数的含义如下:
    IF 条件=值1 THEN
        RETURN(翻译值1)
    ELSIF 条件=值2 THEN
        RETURN(翻译值2)
        ......
    ELSIF 条件=值n THEN
        RETURN(翻译值n)

    ELSE
        RETURN(缺省值)
    END IF
    ·        使用方法:
    1、比较大小
    select decode(sign(变量1-变量2),-1,变量1,变量2) from dual; --取较小值
    sign()函数根据某个值是0、正数还是负数,分别返回0、1、-1

    例如:
    变量1=10,变量2=20
    则sign(变量1-变量2)返回-1,decode解码结果为“变量1”,达到了取较小值的目的。


    2、表、视图结构转化
    现有一个商品销售表sale,表结构为:
    month    char(6)      --月份
    sell    number(10,2)   --月销售金额

    现有数据为:
    200001  1000
    200002  1100
    200003  1200
    200004  1300
    200005  1400
    200006  1500
    200007  1600
    200101  1100
    200202  1200
    200301  1300

    想要转化为以下结构的数据:
    year   char(4)      --年份
    month1  number(10,2)   --1月销售金额
    month2  number(10,2)   --2月销售金额
    month3  number(10,2)   --3月销售金额
    month4  number(10,2)   --4月销售金额
    month5  number(10,2)   --5月销售金额
    month6  number(10,2)   --6月销售金额
    month7  number(10,2)   --7月销售金额
    month8  number(10,2)   --8月销售金额
    month9  number(10,2)   --9月销售金额
    month10  number(10,2)   --10月销售金额
    month11  number(10,2)   --11月销售金额
    month12  number(10,2)   --12月销售金额

    结构转化的SQL语句为:
    create or replace view
    v_sale(year,month1,month2,month3,month4,month5,month6,month7,month8,month9,month10,month11,month12)
    as
        select
        substrb(month,1,4),
        sum(decode(substrb(month,5,2),'01',sell,0)),
        sum(decode(substrb(month,5,2),'02',sell,0)),
        sum(decode(substrb(month,5,2),'03',sell,0)),
        sum(decode(substrb(month,5,2),'04',sell,0)),
        sum(decode(substrb(month,5,2),'05',sell,0)),
        sum(decode(substrb(month,5,2),'06',sell,0)),
        sum(decode(substrb(month,5,2),'07',sell,0)),
        sum(decode(substrb(month,5,2),'08',sell,0)),
        sum(decode(substrb(month,5,2),'09',sell,0)),
        sum(decode(substrb(month,5,2),'10',sell,0)),
        sum(decode(substrb(month,5,2),'11',sell,0)),
        sum(decode(substrb(month,5,2),'12',sell,0))
        from sale
        group by substrb(month,1,4);
  • ORA-01034错误的解决办法

    --Oracle常见错误之一

    事先说明,Oracle高手是不需要看本文的。

    这是个Oracle数据库服务器比较常见的错误。有经验的用户几乎马上就能解决这个错误,再不济也能马上到Metalink(http://metalink.oracle.com)去搜索一下。

    不幸的是,大多的时候,都是初级用户遇到的这样的问题(对他们提Metalink也起不到什么作用--一般都没有上面的帐号:))。所以,这个小帖子可能还有一定的作用。


    问题描述
    =======

    在试图启动数据库的时候,Oracle报告下列错误:
    ERROR:
    ORA-27101 Shared memory realm does not exist
    ORA-01034 ORACLE not available 

    基本解释
    =======
    Error: ORA-27101
    Text: shared memory realm does not exist 
    -------------------------------------------
    Cause: Unable to locate shared memory realm 
    Action: Verify that the realm is accessible


    如何解决 
    =======

    这个问题其实用一句话就可以说清楚:

    ORACLE_HOME或者ORACLE_SID设置不正确。

    在以前的版本中,如果ORACLE_SID不正确,一般都只提示ORA-01034。Oracle 8.1.7 给出一个额外的信息:ORA-27101。

    ->如果是Unix,在Shell里把ORACLE_SID设置正确即可(注意大小写敏感的问题)。
     此外,检查ORACLE_HOME环境变量。如何检查参考如下的命令:

      % echo $ORACLE_SID        
      % ps -ef |grep smon

    ->如果是Windows,一般都是因为系统中有多个实例造成的。

     可以在命令行下 C:\>set ORACLE_SID=DEMO

     把这里的DEMO换为你相应的实例名。

     如果还不行的话,检查注册表中的ORACLE_HOME。


     此外,在Windows环境下有的时候连接不上远程的数据库,会报告如此的错误。

     解决办法是把sqlnet.ora文件中的
     SQLNET.AUTHENTICATION_SERVICES = (NTS) NTS换为NONE.

     现在应该没甚么问题了。什么?还不行?那么建议你Google
      (http://www.google.com )一下
      或者到一些技术论坛(比如说
    ITPub或者CNOUG去看看)。祝你好运!

  • javascript时间脚本收集

    本Blog收集常用的Javascript时间脚本

    正常时间显示

    固定位置的时钟

    背景时钟

    文本框里的时钟

    按钮时钟

    石英钟

    跟随鼠标的钟

    标题栏显示动态时间

    带倒影的时钟

    农历时间显示

    极品万年历

    超强!温度计式样时间

  • 只显示上边框 <table frame=above>
    只显示下边框 <table frame=below>
    只显示左、右边框 <table frame=vsides>
    只显示上、下边框 <table frame=hsides>
    只显示左边框 <table frame=lhs>
    只显示右边框 <table frame=rhs>
    不显示任何边框 <table frame=void>
  •  

    VS.NET 2003 控件命名规范

    1.变量命名规范

    类型
    前缀 示例
    Array
    arr arrShoppingList
    Boolean bln blnIsPostBack
    Byte byt bytPixelValue
    Char chr chrDelimiter
    DateTime dtm dtmStartDate
    Decimal dec decAverageHeight
    Double
    dbl dblSizeofUniverse
    Integer
    int intRowCounter
    Long
    lng lngBillGatesIncome
    Object
    obj objReturnValue
    Short
    shr shrAverage
    Single
    sng sngMaximum
    String
    str strFirstName

    2.控件命名规范

    类型 前缀 示例
    AdRotator adrt adrtTopAd
    Button btn btnSubmit
    Calendar cal calMettingDates
    CheckBox chk chkBlue
    CheckBoxList chkl chklFavColors
    CompareValidator valc valcValidAge
    CustomValidator valx valxDBCheck
    DataGrid dgrd dgrdTitles
    DataList dlst dlstTitles
    DropDownList drop dropCountries
    HyperLink lnk lnkDetails
    Image img imgAuntBetty
    ImageButton ibtn ibtnSubmit
    Label lbl lblResults
    LinkButton lbtn lbtnSubmit
    ListBox lst lstCountries
    Panel pnl pnlForm2
    PlaceHolder plh plhFormContents
    RadioButton rad radFemale
    RadioButtonList radl radlGender
    RangeValidator valg valgAge
    RegularExpression vale valeEmail_Validator
    Repeater rpt rptQueryResults
    RequiredFieldValidator valr valrFirstName
    Table tbl tblCountryCodes
    TableCell tblc tblcGermany
    TableRow tblr tblrCountry
    TextBox txt txtFirstName
    ValidationSummary vals valsFormErrors
    XML xmlc xmlcTransformResults

    3.ADO.NET控件命名规范

    类型
    前缀 示例
    Connection con conNorthwind
    Command cmd cmdReturnProducts
    Parameter parm parmProductID
    DataAdapter dad dadProducts
    DataReader dtr dtrProducts
    DataSet dst dstNorthWind
    DataTable dtbl dtblProduct
    DataRow drow drowRow98
    DataColumn dcol dcolProductID
    DataRelation drel drelMasterDetail
    DataView dvw dvwFilteredProducts

    4.事件处理子程序

    The name of an event-handling subroutine will consist of the ID of the control that rasied the event followed by the type of event being handled. For example, a subroutine named btnSubmit_Click handles the Click event of a Button control named btnSubmit.

    When a control that raises an event is not assigned an ID, the type of the control is used instead of the ID. For example, the subroutine named Button_Click handles the Click event of a Button control without an ID.

  • 1、"&"替换"+"
    2、变量命名大小写,语句错落有秩,源代码维护方面
    3、请养成以下的“对象命名约定”良好习惯
    4、在简单的选择条件情况下,使用IIf()函数
    5、尽量使用Debug.Print进行调试
    6、在重复对某一对象的属性进行修改时,尽量使用With....End With
    7、MsgBox中尽量使用消息图标,这样程序比较有规范
    8、在可能的情况下使用枚举

    1、"&"替换"+"
    在很多人的编程语言中,用“+”来连接字符串,这样容易导致歧义。良好的习惯是用“&”来连接字符串.

    不正确:
    Dim sMessage As String
    sMessage = "1" + "2"

    正确:
    Dim sMessage As String
    sMessage = "1" & "2"

    注意:"&"的后面有个空格

    2、变量命名大小写,语句错落有秩,源代码维护方面

    下面大家比较一下以下两段代码:

    读懂难度很大的代码:

    Dim SNAME As String
    Dim NTURN As Integer

    If NTURN = 0 Then
    If SNAME = "vbeden" Then
    Do While NTURN < 4
    NTURN = NTURN + 1
    Loop
    End If
    End If

    容易读懂的代码:

    Dim sName As String
    Dim nTurn As Integer

    If nTurn = 0 Then
       If sName = "vbeden" Then
          Do While nTurn < 4
              nTurn = nTurn + 1
          Loop
       End If
    End If

    [返回索引]

    3、请养成以下的“对象命名约定”良好习惯

    推荐使用的控件前缀

    控件类型 前缀 例子
    3D Panel  pnl pnlGroup
    ADO Data ado adoBiblio
    Animated button ani aniMailBox
    Check box chk chkReadOnly
    Combo box, drop-down list box cbo cboEnglish
    Command button cmd cmdExit
    Common dialog  dlg dlgFileOpen
    Communications  com comFax
    Control (当特定类型未知时,在过程中所使用的) ctr ctrCurrent
    Data dat datBiblio
    Data-bound combo box dbcbo dbcboLanguage
    Data-bound grid dbgrd dbgrdQueryResult
    Data-bound list box dblst dblstJobType
    Data combo dbc dbcAuthor
    Data grid dgd dgdTitles
    Data list dbl dblPublisher
    Data repeater drp drpLocation
    Date picker dtp dtpPublished
    Directory list box dir dirSource
    Drive list box drv drvTarget
    File list box fil filSource
    Flat scroll bar fsb fsbMove
    Form frm frmEntry
    Frame fra fraLanguage
    Gauge gau gauStatus
    Graph gra graRevenue
    Grid grd grdPrices
    Hierarchical flexgrid flex flexOrders
    Horizontal scroll bar hsb hsbVolume
    Image img imgIcon
    Image combo imgcbo imgcboProduct
    ImageList ils ilsAllIcons
    Label lbl lblHelpMessage
    Lightweight check box lwchk lwchkArchive
    Lightweight combo box lwcbo lwcboGerman
    Lightweight command button lwcmd lwcmdRemove
    Lightweight frame lwfra lwfraSaveOptions
    Lightweight horizontal scroll bar lwhsb lwhsbVolume
    Lightweight list box lwlst lwlstCostCenters
    Lightweight option button lwopt lwoptIncomeLevel
    Lightweight text box lwtxt lwoptStreet
    Lightweight vertical scroll bar lwvsb lwvsbYear
    Line lin linVertical
    List box lst lstPolicyCodes
    ListView lvw lvwHeadings
    MAPI message mpm mpmSentMessage
    MAPI session mps mpsSession
    MCI mci mciVideo
    Menu mnu mnuFileOpen
    Month view mvw mvwPeriod
    MS Chart ch chSalesbyRegion
    MS Flex grid msg msgClients
    MS Tab  mst mstFirst
    OLE container ole oleWorksheet
    Option button opt optGender
    Picture box pic picVGA
    Picture clip clp clpToolbar
    ProgressBar prg prgLoadFile
    Remote Data rd rdTitles
    RichTextBox rtf rtfReport
    Shape shp shpCircle
    Slider sld sldScale
    Spin spn spnPages
    StatusBar sta staDateTime
    SysInfo sys sysMonitor
    TabStrip tab tabOptions
    Text box txt txtLastName
    Timer tmr tmrAlarm
    Toolbar tlb tlbActions
    TreeView tre treOrganization
    UpDown upd updDirection
    Vertical scroll bar vsb vsbRate

    --------------------------------------------------------------------------------
    推荐使用的数据访问对象 (DAO) 的前缀
    用下列前缀来指示数据访问对象
    数据库对象 前缀 例子
    Container con conReports
    Database db dbAccounts
    DBEngine dbe dbeJet
    Document doc docSalesReport
    Field fld fldAddress
    Group grp grpFinance
    Index ix idxAge
    Parameter prm prmJobCode
    QueryDef  qry qrySalesByRegion
    Recordset rec recForecast
    Relation rel relEmployeeDept
    TableDef tbd tbdCustomers
    User usr usrNew
    Workspace wsp wspMine

    --------------------------------------------------------------------------------

    应用程序频繁使用许多菜单控件,对于这些控件具备一组唯一的命名约定很实用。除了最前面 "mnu" 标记以外,菜单控件的前缀应该被扩展:对每一级嵌套增加一个附加前缀,将最终的菜单的标题放在名称字符串的最后。下表列出了一些例子。

    推荐使用的菜单前缀
    菜单标题序列 菜单处理器名称
    File Open mnuFileOpen
    File Send Email mnuFileSendEmail
    File Send Fax  mnuFileSendFax
    Format Character mnuFormatCharacter
    Help Contents mnuHelpContents

    当使用这种命名约定时,一个特定的菜单组的所有成员一个接一个地列在 Visual Basic 的“属性”窗口中。而且,菜单控件的名字清楚地表示出它们所属的菜单项。

    为其它控件选择前缀

    对于上面没有列出的控件,应该用唯一的由两个或三个字符组成的前缀使它们标准化,以保持一致性。只有当需要澄清时,才使用多于三个字符的前缀。

    常量和变量命名约定
    除了对象之外,常量和变量也需要良好格式的命名约定。本节列出了 Visual Basic 支持的常量和变量的推荐约定。并且讨论标识数据类型和范围的问题。

    变量应该总是被定义在尽可能小的范围内。全局 (Public) 变量可以导致极其复杂的状态机构,并且使一个应用程序的逻辑非常难于理解。全局变量也使代码的重用和维护更加困难。

    Visual Basic 中的变量可以有下列范围

    范围 声明位置 可见位置
    过程级 过程,子过程或函数过程中的 ‘Private’ 在声明它的过程中
    模块级 窗体或代码模块(.frm、.bas )的声明部分中的 ‘Private’ 窗体或代码模块中的每一个过程
    全局 代码模块(.bas)的声明部分中的 ‘Public’ 应用程序中的每一处

    在 Visual Basic 的应用程序中,只有当没有其它方便途径在窗体之间共享数据时才使用全局变量。当必须使用全局变量时,在一个单一模块中声明它们,并按功能分组。给这个模块取一个有意义的名称,以指明它的作用,如 Public.bas。

    较好的编码习惯是尽可能写模块化的代码。例如,如果应用程序显示一个对话框,就把要完成这一对话任务所需要的所有控件和代码放在单一的窗体中。这有助于将应用程序的代码组织在有用的组件中,并减小它运行时的开销。

    除了全局变量(应该是不被传递的),过程和函数应该仅对传递给它们的对象操作。在过程中使用的全局变量应该在过程起始处的声明部分中标识出来。此外,应该用 ByVal 将参数传递给 Sub 过程及 function 过程,除非明显地需要改变已传递的参数值。

    随着工程大小的增长,划分变量范围的工作也迅速增加。在类型前缀的前面放置单字母范围前缀标明了这种增长,但变量名的长度并没有增加很多。

    变量范围前缀

    范围 前缀 例子
    全局 g gstrUserName
    模块级 m mblnCalcInProgress
    本地到过程 无 dblVelocity

    如果一个变量在标准模块或窗体模块中被声明为 Public,那么该变量具有全局范围。如果一个变量在标准模块或窗体模块中被分别声明为 Private,那么该变量有模块级范围。

    注意: 一致性是卓有成效地使用这种技术的关键;Visual Basic 中的语法检查器不会捕捉以 "p." 开头的模块级变量。

    常量
    常量名的主体是大小写混合的,每个单词的首字母大写。尽管标准 Visual Basic 常量不包含数据类型和范围信息,但是象 i、s、g 和 m 这样的前缀对于理解一个常量的值和范围还是很有用的。对于常量名,应遵循与变量相同的规则。例如:

    mintUserListMax   '对用户列表的最大限制
                      '(整数值,本地到模块)
    gstrNewLine       '新行字符
                      '(字符串,应用程序全局使用)

    变量
    声明所有的变量将会节省编程时间,因为键入操作引起的错误减少了(例如,究竟是 aUserNameTmp,还是 sUserNameTmp,还是 sUserNameTemp)。在“选项”对话框的“编辑器”标签中,复选“要求变量声明”选项。Option Explicit 语句要求在 Visual Basic 程序中声明所有的变量。

    应该给变量加前缀来指明它们的数据类型。而且前缀可以被扩展,用来指明变量范围,特别是对大型程序。

    用下列前缀来指明一个变量的数据类型。

    变量数据类型

    数据类型 前缀 例子
    String (字符串类型) str strFName
    Integer (短整数类型) int intQuantity
    Long (长整数类型) lng lngDistance
    Single (单精度浮点数类型) sng sngAverage
    Double (双精度浮点数类型) dbl dblTolerance
    Boolean (布尔类型) bln blnFound
    Byte (字节类型) byt bytRasterData
    Date (日期类型) dte dteNow
    Currency (货币计算与定点计算类型) cur curRevenue
    Object (对象类型) obj objCurrent
    Variant (变体类型) vnt vntCheckSum

    描述变量和过程名

    变量或过程名的主体应该使用大小写混合形式,并且应该足够长以描述它的作用。而且,函数名应该以一个动词起首,如 InitNameArray 或 CloseDialog。

    对于频繁使用的或长的项,推荐使用标准缩略语以使名称的长度合理化。一般来说,超过 32 个字符的变量名在 VGA 显示器上读起来就困难了。

    当使用缩略语时,要确保它们在整个应用程序中的一致性。在一个工程中,如果一会儿使用 Cnt, 一会儿使用 Count,将导致不必要的混淆。

    用户定义的类型
    在一项有许多用户定义类型的大工程中,常常有必要给每种类型一个它自己的三个字符的前缀。如果这些前缀是以 "u" 开始的,那么当用一个用户定义类型来工作时,快速识别这些类型是很容易的。例如,ucli 可以被用来作为一个用户定义的客户类型变量的前缀。

    [返回索引]

    4、在简单的选择条件情况下,使用IIf()函数

    罗索的代码:
    If nNum = 0 Then
      sName = "sancy"
    Else
      sName = "Xu"
    End If

    简单的代码:
    sName=IIf(nNum=0,"sancy","Xu")

    5、尽量使用Debug.Print进行调试

    在很多初学者的调试中,用MsgBox来跟踪变量值.其实用Debug.Print不仅可以达到同样的功效,而且在程序最后编译过程中,会被忽略.而MsgBox必须手动注释或删除.

    通常:
    MsgBox nName

    应该:
    Debug.Print nName

    6、在重复对某一对象的属性进行修改时,尽量使用With....End With

    通常:
    Form1.Height = 5000
    Form1.Width = 6000
    Form1.Caption = "This is MyLabel"

    应该:
    With Form1
      .Height = 5000
      .Width = 6000
      .Caption = "This is MyLabel"
    End With
    这种结构程序执行效率比较高,特别在循环语句里。

    7、MsgBox中尽量使用消息图标,这样程序比较有规范

    一般来说

    vbInformation 用来提示确认或成功操作的消息

    vbExclamation 用来提示警告的消息

    vbCritical 用来提示危机情况的消息

    vbQuestion 用来提示询问的消息

    [返回索引]

    8、在可能的情况下使用枚举

    枚举的格式为
    [Public | Private] Enum name
    membername [= constantexpression]
    membername [= constantexpression]
    ....
    End Enum

    Enum 语句包含下面部分:

    部分 描述
    Public 可选的。表示该 Enum 类型在整个工程中都是可见的。Enum 类型的缺省情况是 Public。
    Private 可选的。表示该 Enum 类型只在所声明的模块中是可见的。
    name 必需的。该 Enum 类型的名称。name 必须是一个合法的 Visual Basic 标识符,在定义该 Enum 类型的变量或参数时用该名称来指定类型。
    membername 必需的。用于指定该 Enum 类型的组成元素名称的合法 Visual Basic 标识符。
    constantexpression 可选的。元素的值(为 Long 类型)。可以是别的 Enum 类型。如果没有指定 constantexpression,则所赋给的值或者是 0(如果该元素是第一个 membername),或者比其直接前驱的值大 1。

    说明
    所谓枚举变量,就是指用 Enum 类型定义的变量。变量和参数都可以定义为 Enum 类型。Enum 类型中的元素被初始化为 Enum 语句中指定的常数值。所赋给的值可以包括正数和负数,且在运行时不能改变。例如:

    Enum SecurityLevel IllegalEntry = -1 SecurityLevel1 = 0 SecurityLevel2 = 1 End Enum

    Enum 语句只能在模块级别中出现。定义 Enum 类型后,就可以用它来定义变量,参数或返回该类型的过程。不能用模块名来限定 Enum 类型。类模块中的 Public Enum 类型并不是该类的成员;只不过它们也被写入到类型库中。在标准模块中定义的 Enum 类型则不写到类型库中。具有相同名字的 Public Enum 类型不能既在标准模块中定义,又在类模块中定义,因为它们共享相同的命名空间。若不同的类型库中有两个 Enum 类型的名字相同,但成员不同,则对这种类型的变量的引用,将取决于哪一个类型库具有更高的引用优先级。

    不能在 With 块中使用 Enum 类型作为目标。

    Enum 语句示例
    下面的示例演示用 Enum 语句定义一个命名常数的集合。在本例中是一些可以选择的颜色常数用于设计数据库的数据输入窗体。

    Public Enum InterfaceColors
    icMistyRose = &HE1E4FF&
    icSlateGray = &H908070&
    icDodgerBlue = &HFF901E&
    icDeepSkyBlue = &HFFBF00&
    icSpringGreen = &H7FFF00&
    icForestGreen = &H228B22&
    icGoldenrod = &H20A5DA&
    icFirebrick = &H2222B2&
    End Enum

    好处是加快编程速度

  • 软件环境:
    1、Windows 2000+ORACLE 8.1.7
    2、ORACLE安装路径为:C:\ORACLE

    实现方法:
    1、 开始->设置->控制面板->管理工具->服务
    停止所有Oracle服务。

    2、 开始->程序->Oracle - OraHome81->Oracle Installation Products->
    Universal Installer
    卸装所有Oracle产品,但Universal Installer本身不能被删除

    5、 运行regedit,选择HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE,按del键删除这个入口。

    6、 运行regedit,选择HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,滚动
    这个列表,删除所有Oracle入口。

    7、 运行refedit,
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application,
    删除所有Oracle入口。

    8、 开始->设置->控制面板->系统->高级->环境变量
    删除环境变量CLASSPATH和PATH中有关Oracle的设定

    9、 从桌面上、STARTUP(启动)组、程序菜单中,删除所有有关Oracle的组和图标

    10、 删除\Program Files\Oracle目录

    11、 重新启动计算机,重起后才能完全删除Oracle所在目录

    12、 删除与Oracle有关的文件,选择Oracle所在的缺省目录C:\Oracle,删除这个入
    口目录及所有子目录,并从Windows 2000目录(一般为C:\WINNT)下删除以下文
    件ORACLE.INI、oradim73.INI、oradim80.INI、oraodbc.ini等等。

    13、 WIN.INI文件中若有[ORACLE]的标记段,删除该段

    14、 如有必要,删除所有Oracle相关的ODBC的DSN

    15、 到事件查看器中,删除Oracle相关的日志

    说明:
    如果有个别DLL文件无法删除的情况,则不用理会,重新启动,开始新的安装,
    安装时,选择一个新的目录,则,安装完毕并重新启动后,老的目录及文件就可以删除掉了。

  • 1、DataGrid中:
    <asp:HyperLinkColumn Target="_blank" DataNavigateUrlField="m_id" DataNavigateUrlFormatString="view.aspx?id={0}" DataTextField="m_title"></asp:HyperLinkColumn>
    2、DataList、Repeater中
    <asp:Repeater runat="server" id="Repeater1">
    <ItemTemplate>
    <a href='<%#DataBinder.Eval(Container.DataItem,"url")%>'><%#DataBinder.Eval(Container.DataItem,"linkname")%></a><br>
    </ItemTemplate>
    </asp:Repeater>
  •   在ASP.NET的DataGrid数据显示控件编程中,我们有几种方式可以增加DataGrid columns。其中最常见的方法是在web forms设计器中增加,通过在控件工具箱中拖访DataGrid控件到web设计页面,然后在属性生成器中增加Columns列;还有一种方式就是在HTML视图模式下更改HTML代码的方式增加Columns列。但是这两种方式都是在设计时进行的,一旦设计完成就无法更改。其实我们也可以在程序运行时动态的增加或者删除Columns列。在这篇文章中,我将向大家介绍如何编程实现在运行时动态的增加和删除Columns列,其实是通过隐藏或者现实Columns列来实现的。

      DataGrid 的Columns属性是访问datagrid Columns的关键所在。访问这个属性返回的是DataGridColumnCollection这样的一个集合对象,它包含了所有的DataGrigColumn对象。DataGridColumnCollection提供了增加一个DataGrigColumn对象和删除一个已经存在的DataGrigColumn对象的方法。,我们将使用DataGridColumnCollection的Add方法来增加一个DataGrigColumn对象,从而在运行时动态的增加一列到DataGrid中去。一个DataGrigColumn代表DataGrid的一列,DataGrid的Visible属性用来显示或者隐藏一个列。

      好了,下面让大家跟我一起来创建一个DynamicDataGrid的C#的ASP.NET的工程,他有隐藏和显示DataGrid 的每一列的选项。

      在我用VS.NET创建的web application里面,我在设计页面上拖放了一个Panel 控件。在这个panel控件上,我放置了一个DataGrid控件,一个DropDownList控件,两个Button控件用于改变DataGrid控件的属性。最后的设计界面看起来是下图这样的。

      现在我们开始创建两个方法:FillDataGrid()和FillColumnsList()方法。FillDataGrid()用于增加一个列到DataGrid控件和用DataSet数据源来填充它。在这里的我是通过DB.GetDataSet()方法来获取DataSet的。大家可以参照附加的源代码文件(DB.CS)获取更多的细节。

      下面的代码说明了CreateDataGrid()的实现。从代码中可以看出,我创建了三个列,用BoundColumn的DataField属性绑定到Dataset的ID,Name和Address字段。BoundColumn类继承自DataGridColumn类。

    private void CreateDataGrid()
    {
    // Set DataGrid properties
    DataGrid1.AutoGenerateColumns = false;

    // Get a DataSet object filled with data
    DataSet ds = DB.GetDataSet();

    // Create ID column & add to DataGrid
    BoundColumn col = new BoundColumn();
    col.HeaderText="User ID";
    col.DataField="ID";
    DataGrid1.Columns.Add(col);

    // Create Name column & add to DataGrid
    col = new BoundColumn();
    col.HeaderText="User Name";
    col.DataField="Name";
    DataGrid1.Columns.Add(col);

    // Create Address column & add to DataGrid
    col = new BoundColumn();
    col.HeaderText="User Address";
    col.DataField="Address";
    DataGrid1.Columns.Add(col);

    // DataGrid data binding
    DataGrid1.DataSource = ds.Tables[0];
    DataGrid1.DataBind();
    }

      FillColumnsList()方法只是简单的从DataGrid中读取列名,并且将这些列(Columns)名填充到DropDownList控件的下拉列表中去。我们将使用DropDownList控件来选取隐藏或者显示的列。

    private void FillColumnsList(DataGrid grid)
    {
    foreach (DataGridColumn col in grid.Columns)
    {
    ColumnsList.Items.Add(col.HeaderText);
    }
    }

      接着我们来添加HideDataGridColumn()方法来具体的通过index索引和bool值两个参数来显示或者隐藏一个列。在这里,我仅仅是简单的设置Columns列的Visible属性为true或者false.

    private void HideDataGridColumn(int index, bool show)
    {
    DataGrid1.Columns[index].Visible = show;
    }

      最后的工作就是增加Show Column和Hide Column的单击事件处理。正如我们在代码中看到的一样,我只是简单的调用HideDataGridColumn()方法来显示或者隐藏列,当然要传入参数了。

    private void HideColumnBtn_Click(object sender, System.EventArgs e)
    {
    HideDataGridColumn(ColumnsList.SelectedIndex, false);
    this.DataBind();
    }
    private void ShowColumnBtn_Click(object sender, System.EventArgs e)
    {
    HideDataGridColumn(ColumnsList.SelectedIndex, true);
    this.DataBind();
    }

      OK,所有的工作都结束了,我们看看运行的结果如何。你可以通过下拉列表来选择要隐藏或者显示的列,并且只需单击Show或者Hide按钮即可。

  • 2004-08-20

    Datagrid事件响应 - [DotNet]

     Henry手记 - Datagrid事件响应。http://www.microsoft.com/china/community/Column/14.mspx