博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

与自定义控件的用户控件的概述

Posted on 2011-08-24 10:19  itcfj  阅读(374)  评论(1编辑  收藏  举报
ASP.NET 支持语音列

与自定义控件的用户控件的概述

若要自定义您的需要此列 我们想要邀请您提交您的想法有关您感兴趣的主题以及您想要查看的问题解决在将来的知识库文章和支持语音列。您可以提交您的想法和使用 Ask For It 窗体的反馈。还有在窗体在此栏的底部的链接

本页

简介

您 好 !这是 Parag,我使用现在超过一年的 Microsoft ASP.NET 支持组支持工程师。才能加入 Microsoft,工作的基于 Web 的项目和桌面应用程序使用 Microsoft 技术。同时向客户提供高质量的支持,我看过没有自定义的控件周围的一些混乱,且只是我想要花费一些时间来解释自定义控件周围的一些概念。为错误,它看的起 来相信我,一旦您获得它的挂起,您将在一个更好的位置来欣赏 ASP.NET。

概述

在本月的专栏中,我将讨论以下主题:

  • 用户控件是什么?
  • 自定义控件是什么?
  • 基本用户控件和自定义控件之间区别是什么?

我还将介绍几个涉及如状态管理和自定义控件的呈现方式的自定义控件的高级主题。

用户控件是什么?

用 户控件是自定义的、 可重用控件,并且使用由 HTML 和 Web 服务器控件使用相同的技巧。它们提供了一个简单的方法进行分区,并在 ASP.NET Web 应用程序中重复使用常用的用户界面。它们使用相同的工作 Web 窗体页的 Web 窗体编程模型。有关 Web 窗体编程模型的详细信息,请访问以下 Microsoft 开发人员网络 (MSDN) 的网站:

如何创建用户控件

若 要创建用户控件使用此语法是类似于用于创建 Web 窗体页 (.aspx) 语法。唯一的区别是用户控件不包括 <html>,<body>,和 <form>元素,因为在 Web 窗体页承载用户控件。若要进行一个用户控件,请按照下列步骤操作:

  1. 打开一个文本或 HTML 编辑器并创建服务器端代码块公开的所有属性、 方法和事件。
    <script language="C#" runat="server">
       public void button1_Click(object sender, EventArgs e)
       {
          label1.Text = "Hello World!!!";
       }
    </script>
    
  2. 创建用户控件的用户界面。
    <asp:Label id="label1" runat="server"/>
     <br><br>
    <asp:button id="button1" text="Hit" OnClick="button1_Click" runat="server" />
    

如何在 Web 窗体页中使用用户控件

  1. 在 Microsoft Visual Studio.net 2002年、 Microsoft Visual Studio.net 2003年、 Microsoft 可 Visual Studio 的 2005年或任意文本编辑器中创建一个新的 Web 窗体页 (.aspx)。
  2. 声明 @ Register指令。例如对于使用下面的代码。
    <%@ Register TagPrefix="UC" TagName="TestControl" Src="test.ascx" %>
    注意 假设该用户控件和 Web 窗体页中的相同的位置。
  3. 若要使用用户控件在 Web 窗体页中,请 @ Register指令后使用下面的代码。
    <html>
        <body>
              <form runat="server">
                   <UC:TestControl id="Test1" runat="server"/>
              </form>
        </body>  
    </html>
    

如何在代码隐藏文件的 Web 窗体页中以编程方式创建用户控件的实例

前面的示例中实例化以声明方式中使用 @ Register指令在 Web 窗体页的用户控件。但是,您可以动态地实例化用户控件并将其添加到页。下面是执行的操作的步骤:

  1. 在 Visual Studio 中创建一个新的 Web 窗体页。
  2. 导航到代码隐藏文件生成为此 Web 窗体页。
  3. PagePage_Load事件中写入以下 code.
    // Load the control by calling LoadControl on the page class.
    Control c1 = LoadControl("test.ascx");
                
    // Add the loaded control in the page controls collection.	
    Page.Controls.Add(c1);
    
    笔记,您可以动态地添加用户控件在页生命周期的某些事件。

    有关更多的信息,请访问以下网站:
    以编程方式向 Web 窗体页添加控件
    http://msdn2.microsoft.com/en-us/library/kyt0fzt1(vs.71).aspx

    控件执行生命周期
    http://msdn2.microsoft.com/en-us/library/aa719775(vs.71).aspx

    动态 Web 控件回发,Scott Mitchell 通过的视图状态
    http://aspnet.4guysfromrolla.com/articles/092904-1.aspx

如何处理用户控件

当请求与用户控件的一个网页,则会发生下列情况:

  • 页分析器分析 @ Register 指令在 Src 属性中指定的.ascx 文件,并生成一个从 System.Web.UI.UserControl 类派生的类。
  • 分析器然后动态编译该类为程序集。
  • 如果使用的 Visual Studio 然后仅设计时,在 Visual Studio 创建一个代码隐藏文件的用户控件,该文件由设计器本身预编译。
  • 生成完成的动态代码生成和编译过程是用户控件类最后,包括代码隐藏文件的代码 (ascx.cs),以及在.ascx 文件中编写的代码。

自定义控件是什么?

自定义控件是已编译的代码组件,在服务器上执行、 公开对象模型和呈现的标记文本如 HTML 或 XML,像一个普通的 Web 窗体或用户控件一样。

如何选择自定义控件的基类

若要将自定义控件应直接或间接派生新类从 System.Web.UI.Control 类或从 System.Web.UI.WebControls.WebControl类:

  • 如果您希望该控件呈现派生自非可视元素您应该从 System.Web.UI.Control 派生。例如 <meta><head>是派生自非可视呈现的示例。
  • 如果您希望以呈现 HTML 生成客户端计算机上的可视化界面的控件,您应该派生从 System.Web.UI.WebControls.WebControl

如果您想要更改的按钮或标签,如的现有控件的功能您可以直接派生新类与这些现有的类,并且可以更改它们的默认行为。

简言之,Control 类提供了通过它您可以将其放在 Page 类的控件树中的基本功能。WebControl 类将功能添加到基本的 控件 类,用于在客户端计算机上显示可视的内容。例如对于您可以使用 WebControl类以控制外观和样式通过诸如字体、 颜色,和高度等属性。

如何创建和使用一个简单的自定义控件中从 System.Web.UI.Control 使用 Visual Studio

  1. 启动 Visual Studio。
  2. 创建类的库项目并为其指定一个的名称例如对于 CustomServerControlsLib。
  3. 添加到该的项目例如对于 SimpleServerControl.cs 的源文件。
  4. 在参考部分中包括 System.Web 命名空间的引用。
  5. 检查是否在 SimpleServerControl.cs 文件
    System
    System.Collections
    System.ComponentModel
    System.Data
    System.Web
    System.Web.SessionState
    System.Web.UI
    System.Web.UI.WebControls
    
    中包含下列命名空间
  6. 继承 控件 的基类 SimpleServerControls类。
    public class SimpleServerControl : Control
  7. 重写 呈现方法将输出写入到输出流。
    protected override void Render(HtmlTextWriter writer) 
    {
    	 writer.Write("Hello World from custom control");
    }
    
    注意HtmlTextWriter 类有 HTML 写入文本流的功能。Write 方法 HtmlTextWriter 类的输出到 HTTP 响应流指定的文本,并与 Response.Write 方法相同。
  8. 编译类库项目。它将生成 DLL 输出。
  9. 打开现有的或创建一个新的 ASP.NET Web 应用程序项目。
  10. 添加可用于自定义控件在 Web 窗体页。
  11. ASP.NET 项目的参考部分中添加对类库的引用。
  12. 注册自定义控件在 Web 窗体页上。
    <%@ Register TagPrefix="CC " Namespace=" CustomServerControlsLib " Assembly="CustomServerControlsLib " %>
  13. 实例化,或使用自定义控件在 Web 窗体页上的,请 <form>标记中添加下面的代码行。
    <form id="Form1" method="post" runat="server">
        <CC:SimpleServerControl id="ctlSimpleControl" runat="server">
        </CC:SimpleServerControl >
    </form>
    
    注意 在此的代码 SimpleServerControl 是内部类库控件类名。
  14. 运行 Web 窗体页,您将看到从自定义控件输出。

如果您没有使用 Visual Studio,则需要执行以下步骤:

  1. 打开任何文本编辑器。
  2. 创建一个名为 SimpleServerControl.cs,文件并为其编写为在步骤 1 到 14 中给定的代码。
  3. 在 PATH 变量中添加以下路径:
    c:\windows (winnt)\Microsoft.Net\Framework\v1.1.4322
  4. 启动一个命令,并指向 SimpleServerControl.cs 所在的位置。
  5. 运行以下命令:
    csc /t:library/out: CustomServerControlsLib。SimpleServerControl.dll /r:System.dll /r:System.Web.dll SimpleServerControl.cs
    有关 C# 编译器 (csc.exe) 的详细信息,请访问下面的 MSDN 网站:
  6. 若要进行自定义控件在 Web 窗体页上的执行下列操作:
    1. 创建一个 wwwroot 文件夹下的目录。
    2. 启动 Microsoft Internet Information Services (IIS) 经理,并将标记为虚拟根区目录中新的目录。
    3. 创建一个新的目录下的 Bin 文件夹。
    4. 将自定义控件 DLL 复制到 Bin 文件夹中。
    5. 将放置在前面的步骤中新的目录中创建的示例 Web 窗体页。
    6. 运行示例页从 IIS 管理器。

现在,生成一个简单的自定义控件让我们看一下如何公开属性并将其应用该自定义控件上的设计时属性。

如何公开自定义控件的属性

我将在前面的示例生成,并引入一个或多个属性,可以使用 Web 窗体页上的自定义控件时对其进行配置。

下面的示例演示如何定义一个属性,将显示一条消息,该控件从该属性一定数量的控件的属性中指定的时间:

  1. 在文本编辑器中打开 SimpleServerControl.cs。
  2. 添加 SimpleServerControl类中的属性。
    public class SimpleServerControl : Control
    {
       private int noOfTimes;
       public int NoOfTimes
       {
           get { return this.noOfTimes; }
           set { this.noOfTimes = value; }
       } 
       protected override void Render (HtmlTextWriter writer)
       {
         for (int i=0; i< NoOfTimes; i++)
         {
           write.Write("Hello World.."+"<BR>");
         } 
       }
    }
    
  3. 编译自定义控件。
  4. 若要用于 Web 窗体页上自定义控件将新属性添加到控件声明中。
    <CC:SimpleServerControl id="ctlSimpleControl" NoOfTimes="5" runat="server"></CC:SimpleServerControl>
  5. 运行页将显示消息"hello 世界"从任意次自定义控件作为控件的属性中指定。

如何应用自定义控件上的设计时属性

为什么需要设计时属性

您在前面的示例生成的自定义控件将按预期工作。但是,如果想要在 Visual Studio 中使用该控件,您可能需要突出自动显示在属性窗口中时自定义控件时选定设计时 NoOfTimes 属性。

若 要使这一点,您需要向可执行该操作通过调用属性的 Visual Studio 中使用一种功能的 Visual Studio 提供元数据的信息。 属性可以定义一个类、 方法、 一个属性或字段。Visual Studio 加载自定义控件的类时, 它将检查在类、 方法、 属性或字段级别定义的任何属性,并会相应地更改设计时时自定义控件的行为。

若要有关属性的详细信息请访问下面的 MSDN 网站:

让我们通常使用的示例生成用于属性:

  1. 在文本编辑器中打开 SimpleServerControl.cs。
  2. 引入了一些基本属性类级例如对于 DefaultPropertyToolboxDataTagPrefixAttrbute。我们将这三个属性上生成我们的示例
            [
    	// Specify the default property for the control.		
    	DefaultProperty("DefaultProperty"),
    	
    	// Specify the tag that is written to the aspx page when the
            // control is dragged from the Toolbox to the Design view. 
    	// However this tag is optional since the designer automatically 
    	// generates the default tag if it is not specified.		
    	ToolboxData("<{0}:ControlWithAttributes runat=\"server\">" +
    		"</{0}:ControlWithAttributes>")
    	]
    	public class ControlWithAttributes : Control
    	{
    		private string _defaultProperty;
    		public string DefaultProperty
    		{
    			get { return "This is a default property value"; }
    			set { this._defaultProperty = value; }
    		}
    
    		protected override void Render(HtmlTextWriter writer)
    		{
    			writer.Write("Default Property --> <B>" + 
    			DefaultProperty + "</B>");
    		}
             }
    
  3. 没有一个称为 TagPrefixAttrbute 的多个标记。它是程序集级属性时将控件从工具箱拖动到设计器提供的标记前缀。 否则,在设计器生成一个前缀,如"cc1"默认情况下。TagPrefixAttrbute 不会直接应用到控件类中。若要应用 TagPrefixAttrbute、 打开 AssemblyInfo.cs、 包括下面的代码,行和然后重新生成该项目
    [assembly:TagPrefix("ServerControlsLib ", "MyControl")]
    笔记,如果您想要生成使用命令行来源您需要创建 AssemblyInfo.cs 文件、 将该文件包含所有源代码文件的目录中并运行以下命令来生成控件:
    > csc /t:library/out: ServerControlsLib.dll /r:System.dll /: System.Web.dll *.cs

基本用户控件和自定义控件之间区别是什么?

现在,您已经基本了解什么是用户控件和自定义控件以及如何创建它们的让我们快速浏览一下这两种差异。

因素 用户控件 自定义控件
部署 为单个应用程序方案设计

与应用程序的源代码一起部署在源窗体 (.ascx)

如果在同一控件要在多个应用程序中使用它引入了冗余和维护问题
设计,以便它可由多个应用程序

部署应用程序的 Bin 目录中或在全局程序集缓存中

分布式轻松和没有与冗余和维护相关的问题
创建 创建功能类似于 Web 窗体页的创建 ; 适合应用程序快速开发 (RAD) 方式 编写包括许多代码,因为没有设计器支持
内容 更多好的选择时需要固定的布局中的静态内容,例如对于时所做的页眉和页脚 更适合于当应用程序需要动态时要显示的内容 ; 可以重复使用一个的应用程序跨例如对于为一个数据绑定与动态行的表控件
设计 书写不需要设计因为它们在设计时创作,主要包含静态数据很多应用程序 从零开始的写入要求很好的了解控件的生命周期和是通常注意的用户控件中的事件执行的顺序

高级的主题

接下来,让我们看看一些高级的功能,您可能开发的自定义控件时使用。

状态管理

web 应用程序基于 HTTP,是无状态。页面和它的子控件在每个请求上创建和请求结束后被释放。若要能够在传统的 ASP 编程中的状态中,您将使用会话和应用程序对象。但是,为该,您需要做大量的编码。为避免出现这种情况,ASP.NET 提供了一种机制,称为视图状态在多个请求间维护状态。要进一步了解状态管理和视图状态,请访问以下 MSDN 网站:

使用视图状态在自定义控件示例

ViewStateExample.cs

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;

namespace ServerControlLib
{
	/// <summary>
	/// When a page framework reloads this control after postback, it   
        /// will restore the values which are in view state.
	/// This control can easily perform state management without 
        /// implementing our own logic for maintaining the state.
	/// </summary>
	public class ViewStateExample : WebControl
	{
		// Text to be displayed in Text box control.
		private string _text;
		
		/*
		 * This property needs to be populated before every 
                 * postback in order to 
		 * retain its value.
		*/ 
		public string Text
		{
			get { return (_text == null) ? "_text property is empty"  : _text; }
			set { _text = value; }
		}

		/*
		 * This property needs to be filled once and should be 
                 * available on the successive postbacks.
		*/ 
		public string TextInViewState
		{
			get
			{
				object o = ViewState["TextInViewState"];
				return (o == null) ? "View state is empty" : (string)o;
			}
			set { ViewState["TextInViewState"] = value; } 
		}

		/*
		 * Over-ridden method on WebControl base class which                   
                 * displays both of the property values 
		 * i.e. one stored in view state and other which is not 
                 * saved in view state.
		*/
		protected override void RenderContents(HtmlTextWriter writer)
		{
			writer.Write("Text Without View State = ");
			writer.Write(Text);
			writer.Write("<hr><br>");
			writer.Write("Text In View State = ");
			writer.Write(TextInViewState);
		}
	}
}
使用 Web 窗体页上所选的控件示例

ViewStateExampleDemo.aspx

<%@ Page Language="C#" %>
<%@ Register TagPrefix="CC" Namespace="ServerControlLib" Assembly = "ServerControlLib" %>

<html>
  <head>
    <script runat="server">
      void button1_Click(object sender, EventArgs e)
      {
          Control1.Text = textbox1.Text;
          Control1.TextInViewState = textbox2.Text;
      }
    </script>
  </head>
  <body>
    <form runat="server" ID="Form1">
      <br>
      Property Value Without View State: <asp:TextBox id="textbox1" 
        runat="server" />
      <br>
      Property Value with View State: <asp:TextBox id="textbox2" 
        runat="server" />

      <asp:Button text="Cause Postback" onClick="button1_Click" 
        id="button1" Runat="server" />

      Output from the ViewStateExample Control :
      <CC:ViewStateExample id="Control1" runat="server"/>
    </form>
  </body>
</html>

呈现

在这一节中我将简要介绍从 Control 类或 WebControl类派生自定义控件时应重写哪些方法。

呈现 System.Web.UI.Control 类的方法

System.Web.UI.Control类的呈现方法的信息,请访问以下 MSDN 网站:

在页上呈现控件的方式

每个页都有一个类型的值,该值代表集合,该网页的所有子控件的控件树。若要呈现控件树,HtmlTextWriter 类的对象,将创建包含要在客户端计算机上呈现 HTML。该对象传递给 RenderControl 方法。反过来,RenderControl 方法调用 呈现 方法。然后,Render 方法调用 RenderChildren方法上进行递归循环,直到到达集合的末尾的每个子控件。最好是通过下面的代码示例说明此过程。

public void RenderControl(HtmlTextWriter writer) 
{
    // Render method on that control will only be called if its visible property is true.
    if (Visible)
    {
        Render(writer);
    }
}

protected virtual void Render(HtmlTextWriter writer) 
{
    RenderChildren(writer);
}
protected virtual void RenderChildren(HtmlTextWriter writer) 
{
    foreach (Control c in Controls) 
    {
        c.RenderControl(writer);
    }
} 
呈现 System.Web.UI.WebControl 类的方法

System.Web.UI.WebControl类的呈现方法的信息,请访问以下 MSDN 网站:

如何进行 WebControl 类的呈现

下面的代码示例显示了用于自定义控件的 呈现方法。

protected override void Render(HtmlTextWriter writer)
{
    RenderBeginTag(writer);
    RenderContents(writer);
    RenderEndTag(writer);
}

您不需要重写 呈现WebControl 类的方法。如果要呈现 WebControl 类中的内容则需要重写 RenderContents 方法。但是,如果您仍然希望重写 呈现 方法您必须重写 RenderBeginTag 方法,以及特定的以前的代码示例所示顺序 RenderEndTag方法。

结束时

这就现在用户控件和自定义控件在 ASP.NET 1.0 和 ASP.NET 1.1 版中的。我希望此列可帮助您了解基本的区别以及可以采取制定它们的各种方法。

感谢您的时间。我们期望在不久的将来编写有关该高级主题等状态管理、 控件样式、 复合的控件和自定义的控件的设计时支持的自定义控件的详细信息。

有关控件的详细信息请访问以下 MSDN 网站: