C#.net中web工程中创建用户控件和被调用的方法

http://blog.csdn.net/zzmdegm/article/details/1588705

在进行Web开 发时通常会出现这样的情况:即可用的工具的功能虽然强大,但不符合具体项目的需求,可能是给定控件的工作方式并不像所期望的那样,也可能是一部分代码本来 的目的是能够在多个页上重用,但是许多开发人员实现起来却相当复杂。在这些情况下,定制控件的建立就尤为迫切。简言之,定制控件可以把多个现有的控件包装 在一起,这些现有控件还可能有指定布局的额外属性;定制控件也可以与现有的控件完全不同。使用定制控件与使用ASP.NET中的控件一样简单,能使Web站点的编码非常容易。

在过去,实现定制控件是非常复杂的,尤其在大型系统中,由于使用定制控件需要复杂的注册过程,因此定制控件的实现就更为复杂。即使在简单的系统上,创建定制控件所需进行的编码也是一个相当复杂的过程。老版本Web语言的脚本编码功能也不能对手工编写的对象模型提供较好地访问,因此各个方面的性能都比较差。

.NET Framework使用简单的编程技术,为定制控件的创建提供了一个理想的设置。ASP.NET服务器控件的每个方面都可以随意定制,包括模板制作、客户端脚本编码等功能。但是,也不必为所有这些功能编写代码;控件越简单,创建就越容易。

另外,.NET系统中固有的程序集动态查询使Web应用程序在新Web服务器上的安装如同复制包含代码的目录结构一样简单。要使用自己创建的控件,只需复制包含这些控件的程序集和其他代码即可。甚至可以把频繁使用的控件放在Web服务器上一个位于全局程序集缓存器(GAC)的程序集中,这样服务器上所有的Web应用程序就可以访问它们了。

本章将介绍两类不同的控件:

       用户控件——即把现有的ASP.NET页转化为控件

       定制控件——即组合几个控件的功能、扩展现有的控件以及从头创建新的控件

我们将创建一个简单的控件,显示一副扑克牌(黑桃、方块、红桃和梅花),以便轻松地把它嵌入到其他ASP.NET页面中,以此来阐明用户控件的用法。对于定制控件,则创建一个投票控件,它允许用户在列表中选择一个候选人进行投票,并查看投票过程。

27.1  用户控件

用户控件是用ASP.NET代码创建的控件,就像在标准的ASP.NET Web页面中创建控件一样,不同之处在于一旦创建了用户控件,就可以在多个ASP.NET页面中重用它们。

例如,假定已经创建了一个显示数据库中信息的页面,信息也许是关于订单的,就不必创建一个固定的页面去显示信息,而是可以把相关的代码放到用户控件中,然后把该控件插入到任意多个不同的Web页面中。

此外,可以给用户控件定义属性和方法,例如,可以指定Web页面上显示数据库表时的背景色属性,或者指定一个方法,重新进行数据库查询以检查数据库中的变化。

下面创建一个简单的用户控件,与其他章节一样,本章的示例项目也可以从Wrox网站www.wrox.com上下载。

一个简单的用户控件

VS.NET中,创建一个新Web应用程序PCSUserCWebApp1。一旦生成标准文件,就可以选择Project | Add New Item菜单选项,添加名称为PCSUserC1.ascxWeb用户控件,如图27-1所示。

 

图  27-1

给项目添加的文件的扩展名为.ascx.ascx.cs,它们的工作方式与前面的.aspx文件非常相似。.ascx文件将包含ASP.NET代码,看起来与普通的.aspx文件非常相似。.ascx.cs文件是代码后置文件,它定义了用户控件,定义的方式与在.aspx.cs文件中定义窗体的方式一样。

.aspx文件相似,也可以在设计或HTML视图中查看.ascx文件。在HTML视图中查看文件,可以发现一个重要的区别:.ascx文件没有显示HTML代码,特别是没有<form>元素,原因在于:用户控件要插入到其他文件的ASP.NET窗体中,因此不需要自己的窗体标记。生成的代码如下所示。

<%@ Control Language="c#" AutoEventWireup="false" Codebehind="PCSUserC1.ascx.cs"

    Inherits="PCSUserCWebApp1.PCSUserC1"

    TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>

这非常类似于在.aspx文件中生成的<%@ Page %>指令,但指定了Control,而不是Page,并包括一个TargetSchema属性。这个属性指定控件是为哪个浏览器创建的。在本例中是Internet Explorer 5,这会影响可以从VS.NET工具箱中添加的项目。

查看.aspx.cs文件中生成的代码,可以发现另一个与ASP.NET页面的重要区别:所生成的类是从System.Web.UI.UserControl继承来的。这也是因为控件将用在窗体中,控件并不是窗体。

本例的简单控件是一个显示图形的控件,显示的图形对应于扑克牌中的一种花色(即梅花、方块、红桃和黑桃)。这里所需的图形是VS.NET附带的图形;它们在C:/Program Files/Microsoft Visual Studio .NET 2003/Common7/Graphics/bitmaps/assorted目录中,其文件名分别是CLUB.BMPDIAMOND.BMPHEART.BMPSPADE.BMP。把这些图形文件复制到项目目录中,以便在后面使用它们。

给新控件添加一些代码。在PCSUserC1.ascxHTML视图中添加下列代码:

<%@ Control Language="c#" AutoEventWireup="false" Codebehind="PCSUserC1.ascx.cs"

    Inherits="PCSUserCWebApp1.PCSUserC1"

    TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>

<table cellspacing=4>

   <tr valign="middle">

      <td>

         <asp:Image Runat="server" ID="suitPic" ImageURL="club.bmp"/>

      </td>

      <td>

         <asp:Label Runat="server" ID="suitLabel">Club</asp:Label>

      </td>

   </tr>

</table>

这段代码定义了控件的默认状态,即一个梅花图形和一个标签。在给控件添加额外功能之前,首先把这个控件添加到项目的Web页面WebForm1.aspx上,测试这个默认状态。

为了在.aspx文件中使用定制的控件,首先需要指定如何引用该控件,也就是说,如何在HTML中引用代表控件的标记名称。为此,在代码的最前面使用<%Register%>指令,如下所示。

<%@ Register TagPrefix="PCS" TagFTEL="UserC1" Src="PCSUserC1.ascx" %>

属性TagPrefixTagName指定要使用的标记名称(指定的格式为<TagPrefix:TagName>),使用属性Src指向包含用户控件的文件。现在,添加下面的元素,就可以使用控件了:

      <form id="Form1" method="post" runat="server">

         <PCS:UserC1 Runat="server" ID="myUserControl"/>

      </form>

在窗体的后台编码文件中,用户控件没有在默认状态下声明,因此也需要给WebForm1.aspx.cs添加下面的声明:

   public class WebForm1 : System.Web.UI.Page

   {

           //申明一个用户控件             

      protected PCSUserCWebApp1.PCSUserC1 myUserControl;

      ...

这就是测试用户控件所需要做的所有工作,运行项目的结果如图27-2所示。

 

图  27-2

可以看出,这个控件组合了两个现有的控件,即图形控件和标签控件,因此它属于合成控件一类。

为了控制显示的花色图形,可以在元素<PCS:UserC1>上使用属性。用户控件元素上的属性会自动映射到用户控件的特性上,因此,只需给控件的后台编码PCSUserC1.ascx.cs添加特性。这个特性称为Suit,让它接收合适的花色值。为了便于表示控件的状态,在PCSUserC1.ascx.cs文件中定义命名空间PCSUserCWebApp1中的一个枚举,以保存4个花色名称:

namespace PCSUserCWebApp1

{

   ...

   public enum suit

   {

      club, diamond, heart, spade

   }

   ...

}

PCSUserC1需要一个成员变量,以保存花色类型currentSuit

   public class PCSUserC1 : System.Web.UI.UserControl

   {

      protected System.Web.UI.WebControls.Image suitPic;

      protected System.Web.UI.WebControls.Label suitLabel;

      protected suit currentSuit;

再添加一个访问这个成员变量的属性Suit

      public suit Suit

      {

         get

         {

            return currentSuit;

         }

         set

         {

            currentSuit = value;

            suitPic.ImageUrl = currentSuit.ToString() + ".bmp";

            suitLabel.Text = currentSuit.ToString();

         }

      }

这里的set存取器把图形的URL设置为前面复制的一个文件,并把要显示的文本设置为花色名称。

下面需要给WebForm1.aspx添加代码以访问这个新的属性。使用刚才添加的属性选择花色:

<PCS:UserC1 Runat="server" id="myUserControl" Suit="diamond"/>

ASP.NET处理器可以从提供的字符串中选择出正确的枚举项。但为了使该控件更有趣、更吸引人,下面使用一个单选按钮列表来选择花色:

      <form id="Form1" method="post" runat="server">

         <PCS:UserC1 Runat="server" ID="myUserControl"/>

         <asp:RadioButtonList Runat="server" ID="suitList"

                              AutoPostBack="True">

            <asp:ListItem Value="club" Selected="True">Club</asp:ListItem>

            <asp:ListItem Value="diamond">Diamond</asp:ListItem>

            <asp:ListItem Value="heart">Heart</asp:ListItem>

            <asp:ListItem Value="spade">Spade</asp:ListItem>

         </asp:RadioButtonList>

      </form>

还需要给列表的SelectedIndexChanged事件添加事件处理程序。双击设计视图中的单选按钮列表,就可以添加处理程序。

注意:

把列表的autopostback属性设置为true,是因为除非进行回送操作,否则将不在服务器上执行suitList_SelectedIndexChanged事件处理程序,在默认状态下,这个控件也不会触发回送  操作。

WebForm1.aspx.cx中,方法suitList_SelectedIndexChanged()需要以下代码:

      protected void suitList_SelectedIndexChanged(object sender,

                                                   System.EventArgs e)

      {

         myUserControl.Suit = (suit)Enum.Parse(typeof(suit),

                                               suitList.SelectedItem.Value);

      }

我们知道,元素<ListItem>上的value属性代表前面定义的枚举suit的有效值,因此简单地把这些值解析为枚举类型,并把它们用作用户控件的Suit属性值。使用简单的数据类型转换语法,就可以把返回的对象类型转换为suit,因为这个类型不能通过隐式转换而得到。

在运行Web应用程序时,可以改变花色,如图27-3所示。

 

图  27-3

接下来,给控件添加一些方法。这是非常简单的,只需给PCSUserC1类添加方法就可以了:

      public void Club()

      {

         Suit = suit.club;

      }

      public void Diamond()

      {

         Suit = suit.diamond;

      }

      public void Heart()

      {

         Suit = suit.heart;

      }

      public void Spade()

      {

         Suit = suit.spade;

      }

4个方法Club()Diamond()Heart()Spade()分别用于改变显示在屏幕上的扑克牌的花色。

.aspx页面上的4ImageButton控件上调用这些函数:

         </asp:RadioButtonList>

         <asp:ImageButton Runat="server" ID="clubButton"

                          ImageUrl="CLUB.BMP"

                          OnClick="clubButton_Click"/>

         <asp:ImageButton Runat="server" ID="diamondButton"

                          ImageUrl="DIAMOND.BMP"

                          OnClick="diamondButton_Click"/>

         <asp:ImageButton Runat="server" ID="heartButton"

                          ImageUrl="HEART.BMP"

                          OnClick="heartButton_Click"/>

         <asp:ImageButton Runat="server" ID="spadeButton"

                          ImageUrl="SPADE.BMP"

                          OnClick="spadeButton_Click"/>

      </form>

事件处理程序如下:

      protected void clubButton_Click(object sender,

                                System.Web.UI.ImageClickEventArgs e)

      {

         myUserControl.Club();

         suitList.SelectedIndex = 0;

      }

      protected void diamondButton_Click(object sender,

                                   System.Web.UI.ImageClickEventArgs e)

      {

         myUserControl.Diamond();

         suitList.SelectedIndex = 1;

      }

      protected void heartButton_Click(object sender,

                                 System.Web.UI.ImageClickEventArgs e)

      {

         myUserControl.Heart();

         suitList.SelectedIndex = 2;

      }

      protected void spadeButton_Click(object sender,

                                 System.Web.UI.ImageClickEventArgs e)

      {

         myUserControl.Spade();

         suitList.SelectedIndex = 3;

      }

既然有了4个新按钮,就可以改变扑克牌的花色,如图27-4所示。

 

图  27-4

完成了用户控件的创建后,使用<%@Register%>指令和为控件创建的两个源代码文件(PCSUserC1.ascxPCSUserC1.ascx.cs),就可以在其他的Web页面中使用这个用户控件了。

 

 

 

 

 

 

 

 

下面是完整项目代码:

用户控件:PCSUSerC1.ascx

<%@ Control Language="c#" AutoEventWireup="false" Codebehind="PCSUSerC1.ascx.cs" Inherits="PCSUserCWebApp1.PCSUSerC1" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>

<table cellspacing="4">

       <tr valign="middle">

              <td>

                     <asp:Image id="suitPic" runat="server" ImageUrl="pic/CLUB.BMP"></asp:Image></td>

              <td>

                     <asp:Label id="suitLabel" runat="server">Club</asp:Label></td>

       </tr>

</table>

图像为:


          27-5          

 

 

 

PCSUSerC1.ascx.cs

namespace PCSUserCWebApp1

{

       using System;

       using System.Data;

       using System.Drawing;

       using System.Web;

       using System.Web.UI.WebControls;

       using System.Web.UI.HtmlControls;

 

       /// <summary>

       ///           PCSUSerC1 的摘要说明。

       /// </summary>

       public class PCSUSerC1 : System.Web.UI.UserControl

       {

              protected System.Web.UI.WebControls.Image suitPic;

              protected System.Web.UI.WebControls.Label suitLabel;

              protected suit currentSuit;

 

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

              {

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

              }
public enum suit{CLUB,DIAMOND,HEART,SPADE}

 

         //控件的属性和方法的定义

         public suit Suit{

              get{return currentSuit;}

 

              set{

                   currentSuit=value;

                   this.suitPic.ImageUrl="pic/"+currentSuit.ToString()+".bmp";

                   this.suitLabel.Text=currentSuit.ToString();

              }

         }

 

         public void Club(){Suit=suit.CLUB;}

 

         public void Diamond(){Suit=suit.DIAMOND;}

 

         public void Heart(){Suit=suit.HEART;}

 

         public void Spade(){Suit=suit.SPADE;}

 

 

WebForm1.aspx(页面调用)

<!-- 注册一个用户控件-->

<%@ Register TagPrefix="PCS" TagName="UserC1" Src="PCSUserC1.ascx"%>

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="PCSUserCWebApp1.WebForm1" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

<HTML>

       <HEAD>

              <title>WebForm1</title>

              <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">

              <meta content="C#" name="CODE_LANGUAGE">

              <meta content="JavaScript" name="vs_defaultClientScript">

              <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

       </HEAD>

       <body MS_POSITIONING="GridLayout">

              <form id="Form1" method="post" runat="server">

                  用户控件:<br>

                     <PCS:USERC1 id="myUserControl" runat="server" Suit="DIAMOND"></PCS:USERC1><br><hr>

                     使用系统控件对用户控件的操作:<br>

                     <asp:ImageButton id="IB_DIAMOND" runat="server" ImageUrl="pic/DIAMOND.BMP"></asp:ImageButton>

                     <asp:ImageButton id="IB_SPADE" runat="server" ImageUrl="pic/SPADE.BMP"></asp:ImageButton>

                     <asp:ImageButton id="IB_HEART" runat="server" ImageUrl="pic/HEART.BMP"></asp:ImageButton>

                     <asp:ImageButton id="IB_CLUB" runat="server" ImageUrl="pic/CLUB.BMP"></asp:ImageButton></form>

       </body>

</HTML>

 

页面图片为:

 

 

    27-6         

 

后台代码:WebForm1.aspx(页面调用)

 

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using PCSUserCWebApp1;

 

namespace PCSUserCWebApp1

{

       /// <summary>

       /// WebForm1 的摘要说明。

       /// </summary>

       public class WebForm1 : System.Web.UI.Page

       {

              protected System.Web.UI.WebControls.ImageButton IB_DIAMOND;

              protected System.Web.UI.WebControls.ImageButton IB_SPADE;

              protected System.Web.UI.WebControls.ImageButton IB_HEART;

              protected System.Web.UI.WebControls.ImageButton IB_CLUB;

             

              //申明一个用户控件

              protected PCSUserCWebApp1.PCSUSerC1 myUserControl;

 

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

              {

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

 

                     //用户控件属性取得

                     string a=myUserControl.Suit.ToString();

              }

 

//用户控件方法的调用

         private void IB_HEART_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              myUserControl.Heart();     

         }

 

         private void IB_SPADE_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              myUserControl.Spade();

         }

 

         private void IB_CLUB_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              myUserControl.Club();

         }

 

         private void IB_DIAMOND_Click(object sender, System.Web.UI.ImageClickEventArgs e)

         {

              myUserControl.Diamond();

         }

 

posted @ 2012-10-10 13:16  sungoody  阅读(742)  评论(0编辑  收藏  举报