ASP.NET 定制控件的开发(二) (1)

翻译|其它|编辑:郝浩|2005-06-21 10:53:00.000|阅读 1038 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


复合控件的创建

创建定制控件的第三种方法是组合二个或二个以上的现有的控件。在下面的例子中,读者将以合同编程人员的身份出现,而我则是客户,我希望读者能够开发一个稍微复杂一些的控件,使我能够用来记录收到的对我的书的询价。

作为客户,我将要求读者开发一个控件,使我能够输入一本或多本书籍,每当点击一本书时,控件就会记录下对该书的点击次数,如下图所示:





这一程序的.aspx文件如下所示,除@ Page命令外,该程序的C#和VB程序是相同的:

利便控件的.aspx文件

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

<%@ Register TagPrefix="OReilly" Namespace="CustomControls" Assembly="CustomControls" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<meta content="Microsoft Visual Studio 7.0" name=GENERATOR>
<meta content=C# name=CODE_LANGUAGE>
<meta content="JavaScript (ECMAScript)" 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">

<OReilly:BookInquiryList
Runat="Server"
id="bookInquiry1">

<OReilly:BookCounter
Runat="server"
BookName="Programming ASP.NET"
ID="Bookcounter1"/>

<OReilly:BookCounter
Runat="server"
BookName="Programming C#"
ID="Bookcounter2" />

<OReilly:BookCounter
Runat="server"
BookName="Teach Yourself C++ 21 Days"
ID="BookCounter3" />

<OReilly:BookCounter
Runat="server"
BookName="Teach Yourself C++ 24 Hours"
ID="Bookcounter4" />

<OReilly:BookCounter
Runat="server"
BookName="Clouds To Code"
ID="Bookcounter5" />

<OReilly:BookCounter
Runat="server"
BookName="C++ From Scratch"
ID="Bookcounter6" />

<OReilly:BookCounter
Runat="server"
BookName="Web Classes From Scratch"
ID="Bookcounter7" />

<OReilly:BookCounter
Runat="server"
BookName="XML Web Documents From Srcatch"
ID="Bookcounter8" />

</OReilly:BookInquiryList>

</FORM>
</body>
</HTML>


在上面的代码中需要注意的是,BookInquiryList组件中包含许多BookCounter元素,其中有一个BookCounter元素是对应着我希望记录的书籍。这个控件非常灵活,我可以对任意数量的书进行记录。每个BookCounter元素有一个用来显示被记录书籍名字的BookName属性。

从图9中我们可以看到,每本书都由一个CountedButton定制控件进行记录,但.aspx文件中没有CountedButton控件的定义,它被完整地封装在了BookCounter定制控件中。

整个体系结构如下所示:


BookInquiry利便控件是由WebControl派生的,实现了INamingContainer,在下面我们会提到。
BookInquiry控件有一个由Control类派生的Controls特性。
在控件集合中有数量不等的BookCounter控件。
BookCounter本身也是一个由WebControl派生得来的复合控件,WebControl也实现了INamingContainer。
BookContainer的每个实例有二个特性:BookName和Count。
Name特性是由Viewstate支持的,而且通过.aspx文件中的BookName BookName初始化。
Count特性授权给private性质的CountedButton对象


使用BookInquiry对象的目的有二个:它是BookCounter对象的容器;它负责绘制它本身并确保它包含的BookCounter对象能够按需求绘制自己。

CountedButton控件的修改

我们需要对CountedButton控件进行一些很小的修改,下面分别是C#和VB.NET版的CountedButton控件。

修改后的CountedButton.cs文件


using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace CustomControls
{
    // 由System.Web.UI.WebControls.Button派生出的定制控件
    public class CountedButton : System.Web.UI.WebControls.Button
     {

       private string displayString;

       // 缺省的构造器
       public CountedButton( )
       {
         displayString = "clicks";
         InitValues( );
        }

       // 重载,显示字符串
  public CountedButton(string displayString)
   {
    this.displayString = displayString;
    InitValues( );
    }

// 由构造器调用的函数
private void InitValues( )
{
   if (ViewState["Count"] == null)
   ViewState["Count"] = 0;
   this.Text = "Click me";
}

// Count是ViewState中的一个特性

public int Count
{
   get
   {
     // 在构造器中初始化,不能是NULL
     return (int) ViewState["Count"];
    }

  set
  {
     ViewState["Count"] = value;
   }
}

   // 覆盖OnClick事件处理程序,增大Count变量的值,并在更新按钮上的文本后调用基础类中的方法
protected override void OnClick(EventArgs e)
{
   ViewState["Count"] = ((int)ViewState["Count"]) + 1;
   this.Text = ViewState["Count"] + " " + displayString;
   base.OnClick(e);
   }
  }
}


修改后的CountedButton.vb文件


Imports System.ComponentModel
Imports System.Web.UI
Imports System.Web.UI.WebControls

' 从System.Web.UI.WebControls.Button中派生的定制控件
Public Class CountedButton
Inherits System.Web.UI.WebControls.Button

Private displayString As String

' 构造器对ViewState进行初始化
Public Sub New( )
   displayString = "clicks"
   Init( )
End Sub

' 重载,显示字符串

Public Sub New(ByVal displayString As String)
   Me.displayString = displayString
   Init( )
End Sub

' 由构造器调用的方法
Private Shadows Sub Init( )
  If ViewState("Count") = Is Nothing Then
     ViewState("Count") = 0
     Me.Text = "Click me"
  End If
End Sub

' Count是ViewState中的一个特性
Public Property Count( ) As Integer
Get
   Return CInt(ViewState("Count"))
End Get
   Set(ByVal Value As Integer)
      ViewState("Count") = Value
   End Set
End Property

' 覆盖OnClick事件处理程序,增大Count变量的值,并在更新按钮上的文本后调用基础类中的方法
Protected Overrides Sub OnClick(ByVal e As EventArgs)
    ViewState("Count") = CInt(ViewState("Count")) + 1
        Me.Text = CStr(ViewState("Count") & " " & displayString
        MyBase.OnClick(e)
End Sub
End Class?)


由于我们希望按钮上显示“5 Inquiries”而不是“5 clicks”字符串,因此必须修改OnClick方法中修改按钮字符串文本的代码:

this.Text = ViewState["Count"] + " " + displayString;


相应的VB.NET代码是:

Me.Text = ViewState("Count") & " " & displayString


我们还使用了一个private性质的成员变量displayString来存储传递给构造器中的数值:

private string displayString;


在VB.NET中的代码为:

Private displayString As String


我们必须在构造器中设置这一字符串。为了保护已经使用了缺省的构造器的代码,我们必须重载构造器,新增加一个带有字符串参数的构造器:

public CountedButton(string displayString)
{
    this.displayString = displayString;
    Init( );
}



在VB.NET中的代码是:

Public Sub New(ByVal displayString As String)
Me.displayString = displayString
Initialize( )
End Sub



我们可以对缺省的构造器进行修改,将displayString成员变量有值设置为一个合理的缺省值。其C#代码如下:

public CountedButton( )
{
    displayString = "clicks";
    InitValues( );
}


相应的VB.NET代码是:


Public Sub New( )
    displayString = "clicks"
    Init( )
End Sub




二个构造器的代码都没有考虑private性质的辅助方法Init,它能够保证Count特性被初始化为0,并设置最初时按钮显示的字符串:

private void Init( )
{
   if (ViewState["Count"] == null)
   ViewState["Count"] = 0;
   this.Text = "Click me";
}


在VB.NET中,相应的代码为:


Private Shadows Sub Init( )
If ViewState("Count") = Nothing Then
   ViewState("Count") = 0
   Me.Text = "Click me"
End If
End Sub


作了上述的修改后,我们就可以在第一个复合控件━━BookCounter中使用CountedButton了。
 


BookCounter复合控件的创建


BookCounter复合控件用于记录和显示对某一本书查询的次数,下面分别是C#和VB.NET版的BookCounter复合控件的源代码:

C#版本的BookCounter控件源文件:BookCounter.cs


using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace CustomControls
{
public class BookCounter :
System.Web.UI.WebControls.WebControl,
INamingContainer
{

// 初始化按钮成员
CountedButton btn = new CountedButton("inquiries");

public string BookName
{
   get
    {
      return (string) ViewState["BookName"];
    }

  set
  {
    ViewState["BookName"] = value;
  }
}

public int Count
{
   get
   {
     return btn.Count;
    }
   set
   {
     btn.Count = value;
    }
  }

public void Reset( )
{
   btn.Count = 0;
}

protected override void CreateChildControls( )
{
   Controls.Add(btn);
  }
 }
}


VB.NET版的BookCounter控件的源代码: BookCounter.vb


Imports System
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel

Public Class BookCounter
Inherits System.Web.UI.WebControls.WebControl
Implements INamingContainer

' 初始化按钮成员
Public btn As CountedButton = New CountedButton("inquiries")

Public Property BookName( ) As String
  Get
     Return CStr(ViewState("BookName"))
  End Get
  Set(ByVal Value As String)
     ViewState("BookName") = Value
  End Set
End Property

Public Property Count( ) As Integer
Get
   Return btn.Count
End Get
Set(ByVal Value As Integer)
   btn.Count = Value
End Set
End Property

Public Sub Reset( )
btn.Count = 0
End Sub

Protected Overrides Sub CreateChildControls( )
Controls.Add(btn)
End Sub

End Class
 



标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP