演练:为 Web 服务器控件创建基本控件设计器

更新:2007 年 11 月

此演练演示如何创建为 Web 服务器控件提供设计时用户界面 (UI) 的简单控件设计器。

创建自定义 ASP.NET 服务器控件时,可以创建一个关联设计器,以便在 Microsoft Visual Studio 2005 等可视化设计工具中呈现此控件。设计器使宿主环境能够呈现控件的设计时 UI,以便开发人员可以轻松地配置控件的属性和内容。有关设计器功能和可以与自定义控件关联的各种设计器类的更多信息,请参见 ASP.NET 控件设计器概述

通过此演练,您将学会如何执行以下任务:

  • 创建标准的复合控件设计器,并将其与复合控件关联。

  • 创建大小可调的复合控件设计器,并将其与复合控件关联。

  • 创建带有可编辑区域的简单容器控件设计器,并将其与 WebControl 控件关联。此设计器使您能够在设计图面上将文本添加到可编辑区域,还可以将其他控件拖动到此区域中。

  • 在网页上引用自定义控件(及其关联设计器)。

  • 在 Visual Studio 2005 的“设计”视图中使用网页

先决条件

若要完成本演练,您需要:

  • Visual Studio 2005,用来创建承载自定义控件及其关联设计器的网页。

  • ASP.NET 网站,用于承载控件的页面。如果已经配置了一个站点,可以使用该站点作为本演练的起点。否则,请参见如何:在 IIS 5.0 和 6.0 中创建和配置虚拟目录获取有关创建虚拟目录或站点的详细信息。

创建自定义控件和设计器

在本节中,将创建三个简单的 Web 服务器控件以及为每个控件创建关联的自定义控件设计器。

创建代码文件

  1. 在编辑器中,创建带有与您所使用的语言相对应的扩展名且文件名为 SimpleControlDesigners 的新文件。例如,在 Visual Studio 2005 中,创建名为 SimpleControlDesigners.vb 或 SimpleControlDesigners.cs 的新的类文件。

  2. 添加以下使用设计器类时所必需的命名空间引用。以及添加一个包含控件及其关联设计器的命名空间。

    Imports System
    Imports System.ComponentModel
    Imports System.ComponentModel.Design
    Imports System.Drawing
    Imports System.Web.UI
    Imports System.Web.UI.Design
    Imports System.Web.UI.Design.WebControls
    Imports System.Web.UI.WebControls
    
    Namespace Samples.AspNet.VB.Controls
    End Namespace
    
    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Drawing;
    using System.Web.UI;
    using System.Web.UI.Design;
    using System.Web.UI.Design.WebControls;
    using System.Web.UI.WebControls;
    
    namespace Samples.AspNet.CS.Controls 
    {
    }
    
  3. 保存该文件。

现在已经准备好创建复合 Web 服务器控件和关联设计器了。设计器可以与控件处于相同或不同的程序集中;在本演练中,为了方便起见,在相同的代码文件和程序集中创建它们。

创建复合控件和关联设计器

  1. 在 SimpleControlDesigners 文件中声明的命名空间中,为从 CompositeControl 继承的复合控件类创建公共声明,如下面的代码示例所示。

        Public Class SimpleCompositeControl
            Inherits CompositeControl
        End Class
    
     public class SimpleCompositeControl : CompositeControl
        {
        }
    
  2. 将下面的代码示例中显示的公共属性添加到类。这些属性将用于创建网页上的部分 UI。

    Dim _prompt As String = "Please enter your date of birth: "
    Overridable Property Prompt() As String
        Get
            Dim o As Object
            o = ViewState("Prompt")
            If o Is Nothing Then
                Return _prompt
            Else
                Return CType(o, String)
            End If
        End Get
        Set(ByVal value As String)
            ViewState("Prompt") = value
        End Set
    End Property
    
    Overridable Property DOB() As DateTime
        Get
            Dim o As Object
            o = ViewState("DOB")
            If o Is Nothing Then
                Return DateTime.Now
            Else
                Return CType(o, DateTime)
            End If
        End Get
        Set(ByVal value As DateTime)
            ViewState("DOB") = value
        End Set
    End Property
    
    private String _prompt = "Please enter your date of birth: ";
    public virtual String Prompt
    {
        get
        {
            object o = ViewState["Prompt"];
            return (o == null) ? _prompt : (string)o;
        }
        set
        {
            ViewState["Prompt"] = value;
        }
    }
    
    public virtual DateTime DOB
    {
        get
        {
            object o = ViewState["DOB"];
            return (o == null) ? DateTime.Now : (DateTime)o;
        }
        set
        {
            ViewState["DOB"] = value;
        }
    }
    
    
  3. 创建一个方法,将子控件添加到复合控件。下面的方法添加两个文本框和一个分行符,它们在网页上可见。

    Protected Overrides Sub CreateChildControls()
        Dim lab As New Label
    
        lab.Text = Prompt
        lab.ForeColor = System.Drawing.Color.Red
        Me.Controls.Add(lab)
    
        Dim lit As New Literal()
        lit.Text = "<br />"
        Me.Controls.Add(lit)
    
        Dim tb As New TextBox()
        tb.ID = "tb1"
        tb.Text = DOB.ToString()
        Me.Controls.Add(tb)
    
        MyBase.CreateChildControls()
    End Sub
    
    protected override void CreateChildControls() 
    {
        Label lab = new Label();
    
        lab.Text = Prompt;
        lab.ForeColor = System.Drawing.Color.Red;
        this.Controls.Add(lab);
    
        Literal lit = new Literal();
        lit.Text = "<br />";
        this.Controls.Add(lit);
    
        TextBox tb = new TextBox();
        tb.ID = "tb1";
        tb.Text = DOB.ToString();
        this.Controls.Add(tb);
    
        base.CreateChildControls();
    }
    
  4. 创建从 CompositeControlDesigner 派生的简单复合控件设计器类,以便与刚刚创建的复合控件关联。

    尽管可以将多种 UI 呈现功能添加到设计器,但下面的代码示例只是创建设计器并重写基类中的一个关键属性,以防止控件的大小在“设计”视图中被调整。

    Public Class SimpleCompositeControlDesigner
        Inherits CompositeControlDesigner
        ' Set this property to prevent the designer from being resized.
        Public Overrides ReadOnly Property AllowResize() As Boolean
            Get
                Return False
            End Get
        End Property
    End Class
    
    public class SimpleCompositeControlDesigner : CompositeControlDesigner
    {
        // Set this property to prevent the designer from being resized.
        public override bool AllowResize 
        {
            get { return false; }
        }
    }
    
  5. 在复合控件的类声明的正上方,添加 Designer 元数据属性,此属性将控件与刚刚创建的设计器类关联,如下面的代码示例所示。

    <Designer(GetType(SimpleCompositeControlDesigner))> _
    Public Class SimpleCompositeControl
        Inherits CompositeControl
    
    [Designer(typeof(SimpleCompositeControlDesigner))]
    public class SimpleCompositeControl : CompositeControl
    
  6. 保存该文件。

现在已经创建了自定义复合 Web 服务器控件和关联设计器,可以创建从第一个控件派生的第二个控件了。第二个控件的唯一不同之处在于可以在设计图面调整其关联设计器的大小。

创建大小可调的复合控件和关联设计器

  1. 在 SimpleControlDesigners 文件中声明的命名空间中,为从先前创建的 SimpleCompositeControl 控件继承的新复合控件类创建公共声明。下面的代码示例演示新的声明。

        Public Class SimpleCompositeControl2
            Inherits SimpleCompositeControl
        End Class
    
     public class SimpleCompositeControl2 : SimpleCompositeControl
        {
        }
    
  2. 将此控件与 CompositeControlDesigner 基类关联。

    默认情况下,此示例为复合控件创建一个简单的大小可调的设计器。

    <Designer(GetType(CompositeControlDesigner))> _
    Public Class SimpleCompositeControl2
        Inherits SimpleCompositeControl
    End Class
    
    [Designer(typeof(CompositeControlDesigner))]
    public class SimpleCompositeControl2 : SimpleCompositeControl
    {
    }
    
  3. 保存该文件。

创建的前两个控件是与复合控件设计器关联的复合控件。现在,将创建从 WebControl 派生的简单控件,并将其与 ContainerControlDesigner 类关联。当您希望将设计器与单个自定义 Web 服务器控件关联,并在设计图面上提供单个可编辑区域时,此类型的设计器很有用。在这里创建的自定义控件不实现任何实际功能;它的存在只是为了演示 ContainerControlDesigner 类的功能。

12yydcke.alert_note(zh-cn,VS.90).gif说明:

还可以使用与先前所创建的复合控件和设计器类似的复合控件和设计器来提供相同的功能。此示例仅旨在演示如何使用 ContainerControlDesigner 类,并将其与 WebControl 控件关联。

创建 Web 服务器控件和带有可编辑区域的容器设计器

  1. 在 SimpleControlDesigners 文件中声明的命名空间中,为新的 Web 服务器控件类创建公共声明,如下面的代码示例所示。

     Public Class SimpleContainerControl
            Inherits WebControl
            Implements INamingContainer
        End Class
    
     public class SimpleContainerControl : WebControl, INamingContainer
        {
        }
    
  2. 创建容器控件设计器类,并将其与自定义控件关联。实现两个属性:FrameStyle 属性,用于包含设计器的框架的样式;以及 FrameCaption 属性,用于包含框架的标头文本。这些属性提供了框架,以便在设计图面上以可视方式呈现和选择这些控件。下面的代码示例演示了设计器和属性的代码。

    12yydcke.alert_note(zh-cn,VS.90).gif说明:

    ContainerControlDesigner 类自动处理在设计时呈现自定义控件和提供单个可编辑区域的所有其他方面。

    Public Class SimpleContainerControlDesigner
        Inherits ContainerControlDesigner
    
        Dim _style As Style
    
        ' Add the caption by default.
        Public Overrides ReadOnly Property FrameCaption() As String
            Get
                Return "A Simple ContainerControlDesigner"
            End Get
        End Property
    
        Public Overrides ReadOnly Property Framestyle() As Style
            Get
                If _style Is Nothing Then
                    _style = New Style()
                    _style.Font.Name = "Verdana"
                    _style.Font.Size = New FontUnit("XSmall")
                    _style.BackColor = Color.LightBlue
                    _style.ForeColor = Color.Black
                End If
    
                Return _style
            End Get
        End Property
    
    End Class
    
    public class SimpleContainerControlDesigner : ContainerControlDesigner
    {
        private Style _style = null;
    
        // Add the caption by default. Note that the caption 
        // will only appear if the Web server control 
        // allows child controls rather than properties. 
        public override string FrameCaption
        {
            get
            {
                return "A Simple ContainerControlDesigner";
            }
        }
    
        public override Style FrameStyle
        {
            get
            {
                if (_style == null)
                {
                    _style = new Style ();
                    _style.Font.Name = "Verdana";
                    _style.Font.Size = new FontUnit ("XSmall");
                    _style.BackColor = Color.LightBlue;
                    _style.ForeColor = Color.Black;
                }
    
                return _style;
            }
        }
    }
    
  3. 将设计器与控件关联。在 Web 服务器控件的类声明的正上方,添加 Designer 元数据属性。请注意,在这种情况下(如下面的代码示例所示),还可以添加带有 false 参数的 ParseChildren 属性。这将通知设计时分析器将控件的内部内容视为子控件而不是属性。在本例中,您希望将此控件的内部内容视为子控件,以便可以在设计时将其他服务器控件拖动到可编辑区域,并编辑它们的属性。

    <Designer(GetType(SimpleContainerControlDesigner))> _
    <ParseChildren(False)> _
    Public Class SimpleContainerControl
        Inherits WebControl
        Implements INamingContainer
    End Class
    
    [Designer (typeof(SimpleContainerControlDesigner))]
    [ParseChildren (false)]
    public class SimpleContainerControl : WebControl, INamingContainer
    {
    }
    
  4. 保存该文件。

您已经创建了三个自定义控件并将控件设计器与其关联。接下来只需将控件编译到程序集中,然后在可视化设计工具中使用它们。

编译自定义的控件和设计器

  1. 在命令提示中打开创建的 SimpleControlDesigners 文件所在的文件夹。从命令提示中,可以将源代码编译到程序集中。

    12yydcke.alert_note(zh-cn,VS.90).gif说明:

    若要从此位置运行 .NET Framework 编译器,必须已经将 .NET Framework 的安装路径添加到计算机的 PATH 变量。通常,此路径位于 Windows 安装目录下的 \Microsoft.NET\Framework\<version number>。如果尚未更新 PATH 变量,右击“我的电脑”,选择“属性”,单击“高级”选项卡,再单击“环境变量”按钮。在“系统变量”列表中,双击 PATH 变量。在“变量值”文本框中,将一个分号添加到文本框中的现有值的末尾,然后键入您的 .NET Framework 安装的路径。单击“确定”关闭每个对话框。

  2. 使用下面的编译命令将 SimpleControlDesigners 文件中的控件编译到程序集中。

    csc /r:System.dll /r:System.Design.dll /r:System.Drawing.dll /debug+ /r:System.Web.dll /t:library /out:SimpleControlDesignersCS.dll simplecontroldesigners.cs
    
    vbc /r:System.dll /r:System.Design.dll /r:System.Drawing.dll /debug+ /r:System.Web.dll /t:library /out:SimpleControlDesignersVB.dll SimpleControlDesigners.vb
    
  3. 将产生的程序集文件移动到承载控件的页面所属网站的 \Bin 文件夹。

    12yydcke.alert_note(zh-cn,VS.90).gif说明:

    若要编译控件和设计器,Visual Studio 用户需添加一个对 System.Design.dll 的引用。有关更多信息,请参见如何:在网站中添加对某个 .NET 或 COM 组件的引用

创建网页以承载控件

现在已经使用自定义控件及其关联控件设计器创建了程序集,接着将在 Visual Studio 2005 中创建网页以引用这些控件,请查看它们在“设计”视图中的显示方式,然后将页面加载到浏览器中。

创建用于承载控件的网页

  1. 在 Visual Studio 2005 中打开网站,创建名为 ControlDesigners.aspx 的新页面。在页面的顶部,即页面声明的正下方,添加 Register 指令以引用先前创建的程序集和控件,如下面的代码示例所示。

    <%@ Page Language="VB" %>
    <%@ register tagprefix="aspSample" 
      assembly="SimpleControlDesignersVB" 
      namespace="Samples.AspNet.VB.Controls" %>
    
    <%@ Page Language="C#" %>
    <%@ register tagprefix="aspSample" 
      assembly="SimpleControlDesignersCS" 
      namespace="Samples.AspNet.CS.Controls" %>
    
  2. 按下面的代码示例所示完成页面的其余部分,引用先前创建的所有三个控件:SimpleCompositeControl、SimpleCompositeControl2 和 SimpleContainerControl。请注意,若要引用每个控件,请使用在 Register 指令中指定的 aspSample 前缀。

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Designers Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <p style="font-family:tahoma;font-size:large;
                font-weight:bold">
                Simple Control Designers
            </p>
            <div style="font-family:tahoma;font-size:x-small;">
                <span style="font-size: 14pt">
                Composite, no-resize</span>
            </div>
            <aspSample:SimpleCompositeControl id="SimpleControl1" runat="server" />
            <br /><br />
            <div style="font-family:tahoma;font-size:x-small;">
                <span style="font-size: 14pt">
                Composite, resize</span>
            </div>
            <aspSample:SimpleCompositeControl2 id="SimpleControl2" runat="server"  
                height="87px" width="238px" />
            <br /><br />
            <div style="font-family:tahoma;font-size:x-small;">
                <span style="font-size: 14pt">
                    Container</span>
            </div>
            <aspSample:SimpleContainerControl id="SimpleControl3" runat="server" 
                height="57px">
                Type some content here.
            </aspSample:SimpleContainerControl>
            <br /><br />
        </div>
        </form>
    </body>
    </html>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title>Designers Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <p style="font-family:tahoma;font-size:large;
                font-weight:bold">
                Simple Control Designers
            </p>
            <div style="font-family:tahoma;font-size:x-small;">
                <span style="font-size: 14pt">
                Composite, no-resize</span>
            </div>
            <aspSample:SimpleCompositeControl id="SimpleControl1" runat="server" />
            <br /><br />
            <div style="font-family:tahoma;font-size:x-small;">
                <span style="font-size: 14pt">
                Composite, resize</span>
            </div>
            <aspSample:SimpleCompositeControl2 id="SimpleControl2" runat="server"  
                height="87px" width="238px" />
            <br /><br />
            <div style="font-family:tahoma;font-size:x-small;">
                <span style="font-size: 14pt">
                    Container</span>
            </div>
            <aspSample:SimpleContainerControl id="SimpleControl3" runat="server" 
                height="57px">
                Type some content here.
            </aspSample:SimpleContainerControl>
            <br /><br />
        </div>
        </form>
    </body>
    </html>
    
  3. 保存页。

现在可以在“设计”视图中测试页面,以查看控件设计器的工作情况。

演示控件的设计时呈现

  1. 切换到页面的“设计”视图。

    控件应如下面的屏幕快照所示。请注意,第二个复合控件是大小可调的,第一个不是。

    “设计”视图中的 ControlDesigners.aspx 页面
    图:设计视图中的 VS ControlDesigners.aspx

  2. 在容器控件的内容区域中单击,然后为控件键入一些文本内容。

  3. 切换到“源”视图,并找到容器控件的源代码。确认在此区域中键入的文本显示在源代码中。

  4. 切换回“设计”视图。

  5. 单击控件的框架,将鼠标指针悬停在其中一个调整大小图标之上,然后调整容器控件的大小。

  6. 在控件的可编辑区域中,在文本内容的末尾处单击,然后按 Enter 以添加分行符。

  7. 从**“工具箱”拖动 Button 控件,并将其放置到在可编辑区域中输入的文本的下方。从“工具箱”**拖动 Label 控件,并将其放置在按钮的旁边。这说明可以将子控件拖动到可编辑区域中。如有必要,可以在设计时设置子控件的属性,可以添加 Button 控件的代码,以便在运行时更新 Label 控件的 Text 属性。

    刚刚添加了控件的页面应与下面的屏幕快照相似。

    带子控件的容器控件
    带子控件的 VS 容器控件

  8. 保存页。

在运行时查看页

  • 在浏览器中加载页。

    控件应以您在“设计”视图中自定义的方式显示。页面看起来应与下面的屏幕快照类似。

    已完成的控件设计器网页
    VS 简单控件设计器网页

后续步骤

此演练演示了创建与复合控件或容器控件设计器关联的自定义控件时涉及的基本任务。使用设计器创建了自定义控件,此设计器允许您调整控件的大小,以及在 Visual Studio 2005 的“设计”视图中的可编辑区域中添加文本。如需进一步探究此问题,我们建议:

请参见

概念

ASP.NET 控件设计器概述