用户控件

更新:2007 年 11 月

ASP.NET 移动用户控件提供了一种快速高效的方法,使您可以在 ASP.NET 移动网页上创建自己的用户控件。可以将一个或多个控件及其相关逻辑进行组合,然后封装到一个用户控件中,从而在一个移动页中使用其他任何移动页的内容。用户控件和 MobilePage 控件是一样的,但有些例外。

移动用户控件:

  • 文件扩展名必须是 .ascx。

  • 不需要 @ Page 指令。

  • 必须包含 @ Register 指令。

@ Register 指令将别名与命名空间和类关联,以便可以在用户控件中声明移动控件。

ASP.NET 区别用户控件和复合控件。用户控件保持为 .ascx 文本文件,而复合控件在编译后保存在程序集中。在 ASP.NET 移动网页中,用户控件可以包含多个控件,如本主题中的示例所示。

创建用户控件

通过创建带 .ascx 扩展名的文件可创建新的用户控件。下面的代码示例包含一个用户控件,它使用多个标签显示一辆汽车的详细信息。

<%@ Control Language="VB" ClassName="CarControl" 
    Inherits="System.Web.UI.MobileControls.MobileUserControl" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>

<script runat="server">
    ' Private field of externally defined CarInfo type
    Private _car As New CarInfo()

    ' Public Property for the CarInfo
    Public Property Car() As CarInfo
        Get
            Return _car
        End Get
        Set(ByVal value As CarInfo)
            _car = value
        End Set
    End Property
</script>

<mobile:Panel ID="Panel1" Runat="server" BreakAfter="true">
    <mobile:Label id="Label1" runat="server" BreakAfter="true">
        Make: <%# Car.Make %></mobile:Label>
    <mobile:Label id="Label2" runat="server" BreakAfter="true">
        Model: <%# Car.Model %></mobile:Label>
    <mobile:Label id="Label3" runat="server" BreakAfter="true">
        Year: <%# Car.Year %></mobile:Label>
    <mobile:Label id="Label4" runat="server" BreakAfter="true">
        Color: <%# Car.Color %></mobile:Label>
</mobile:Panel>
<%@ Control Language="C#" ClassName="CarControl" 
    Inherits="System.Web.UI.MobileControls.MobileUserControl" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>

<script runat="server">
    // Private field of externally defined CarInfo type
    private CarInfo _car = new CarInfo();

    // Public Property for the CarInfo
    public CarInfo Car
    {
        get { return _car; }
        set { _car = value; }
    }
</script>

<mobile:Panel ID="Panel1" Runat="server" BreakAfter="true">
    <mobile:Label id="Label1" runat="server" BreakAfter="true">
        Make: <%# Car.Make %></mobile:Label>
    <mobile:Label id="Label2" runat="server" BreakAfter="true">
        Model: <%# Car.Model %></mobile:Label>
    <mobile:Label id="Label3" runat="server" BreakAfter="true">
        Year: <%# Car.Year %></mobile:Label>
    <mobile:Label id="Label4" runat="server" BreakAfter="true">
        Color: <%# Car.Color %></mobile:Label>
</mobile:Panel>

部署用户控件

创建移动用户控件之后,可以采用下列方式将该控件添加到 ASP.NET 移动网页:

  • 在页上注册该控件,并在标记中声明该控件。

  • 以编程方式将该控件加载到网页中。

若要注册用户控件,请使用 @ Register 指令。若要以编程方式加载控件,请使用 LoadControl 方法。

下面的示例代码演示如何以声明方式在页中注册和使用自定义控件,以及如何以编程方式加载用户控件。

<%@ Page Language="VB" 
    Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>
<%@ Register TagPrefix="carp" TagName="CarControl" 
    Src="~/CarControl.ascx" %>

<script runat="server">
    Protected Sub Page_Load( _
        ByVal sender As Object, ByVal e As EventArgs)
        ' Set the existing car control's data
        CarCtl.Car = New CarInfo("TreeCars", "Rooter", _
            2003, "Tan")

        ' Load a new car control and set the data
        Dim ccar As CarControl = _
            CType(Page.LoadControl("~/CarControl.ascx"), _
            CarControl)
        ccar.ID = "newCarCtl"
        ' Set the new car control's data
        ccar.Car = New CarInfo("TreeCars", "Climber", _
            2001, "Green")
        ' Add the new car control to form2.Controls
        form2.Controls.Add(ccar)

        ' Bind the data and the controls
        DataBind()
    End Sub
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <mobile:form id="form1" runat="server">
        <carp:CarControl ID="CarCtl" runat="server" /><br />
        <mobile:Link ID="Link1" Runat="server"
            href="#form2" Text="Next" />
    </mobile:form>
    <mobile:form ID="form2" Runat="server">
        <mobile:Link runat="server" id="Link2" 
            BreakAfter="true" 
            Text="Return" href="#form1" />
        <br />
    </mobile:form>
</body>
</html>
<%@ Page Language="C#" 
    Inherits="System.Web.UI.MobileControls.MobilePage" %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>
<%@ Register TagPrefix="carp" TagName="CarControl" 
    Src="CarControl.ascx" %>

<script runat="server">
    protected void Page_Load(
        object sender, EventArgs e)
    {
        // Set the existing car control's data
        CarCtl.Car = new CarInfo("TreeCars", "Rooter", 
            2003, "Tan");

        // Load a new car control and set the data
        CarControl ccar = 
            (CarControl)Page.LoadControl("~/CarControl.ascx");
        ccar.ID = "newCarCtl";
        // Set the new car control's data
        ccar.Car = new CarInfo("TreeCars", "Climber", 
            2001, "Green");
        // Add the new car control to form2.Controls
        form2.Controls.Add(ccar);

        // Bind the data and the controls
        DataBind();
    }

    // Toggles the visible form
    protected void Command_Click(
        object sender, EventArgs e)
    {
        if (this.ActiveForm == form1)
            this.ActiveForm = form2;
        else
            this.ActiveForm = form1;
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <mobile:form id="form1" runat="server">
        <carp:CarControl ID="CarCtl" runat="server" /><br />
        <mobile:Command ID="Command1" Runat="server" 
            OnClick="Command_Click">Next</mobile:Command>
    </mobile:form>
    <mobile:form ID="form2" Runat="server">
        <mobile:Command ID="Command2" Runat="server" 
            OnClick="Command_Click">Return</mobile:Command>
        <br />
    </mobile:form>
</body>
</html>

解析 URL

当创建的页访问位于不同目录中的用户控件时,该用户控件中的所有相对 URL 都被解析为相对于该用户控件的目录,而不是相对于该页的目录。典型情况如下所述:

  • 页的地址为 /Default.aspx。

  • 该页包含用户控件“子文件夹/UserControl.ascx”。

  • 该用户控件又包含用户控件 B.ascx。

在这种情况下,B.ascx 被解析为“子文件夹/B.ascx”。通过这种 URL 解析方式,用户控件可以封装任何链接或该控件可能需要的其他相关资源。

以下 URL 被解析为相对于用户控件:

  • 任何导航 URL,例如 Link 控件的 URL。

  • Image 控件上的图像 URL。

  • Form 控件的操作 URL。

编写控件或控件适配器时,必须确保在必要的地方解析相对 URL。在您的控件和适配器中,调用移动控件的 ResolveUrl 方法,将 URL 解析为相对于包含页或用户控件的目录。适配器基类中的一些帮助器方法自动调用 ResolveUrl 方法来解析超链接。

一种例外情况是,您将 DeviceSpecific 控件包含在一个自定义用户控件中,该用户控件引用 Web.config 文件 <deviceFilters> 节中列出的设备筛选器。在这种情况下,控件使用网页所在目录中的 Web.config 文件,而不是控件的子目录中的 Web.config 文件。

用户控件和窗体引用中的格式设置和链接

可以使用以数字符号 (#) 开头、后跟窗体 ID 的 URL 链接到同一页上的窗体。下面的代码示例使用 Link 控件的 href 属性来指定 URL。

<mobile:Link ID="Link1" Runat="server"
    href="#form2" Text="Next" />

典型情况下,有一个用户控件插入顶层的页中。该页和用户控件可能包含一个或多个窗体。该页和每个用户控件上的控件可以引用彼此内部包含的窗体,依照的规则如下:

  • 当网页上的控件引用子用户控件中的窗体时,URL 必须包含窗体的完整唯一的 ID。格式为 ucid:formid,其中 ucid 是用户控件的 ID,formid 是窗体的 ID。

  • 当用户控件内的控件引用窗体时,ASP.NET 首先在用户控件中搜索窗体,然后在它的父级中搜索,依此类推,一直搜索到页级。

例如,假定页包含两个窗体,其 ID 分别为 FormA 和 FormB。此页还包含一个 ID 为 UserControl1 的顶级用户控件。此用户控件包含两个附加的窗体,其 ID 为 FormA 和 FormC。下表显示本方案的可能 URL 及其行为的示例。

控件位置

窗体 URL

行为

在页上

#FormA

链接到页本身上的 FormA。

在页上

#FormC

引发异常,因为页不包含任何具有指定 ID 的窗体。(只有用户控件具有这种窗体。)

在页上

#UserControl1:FormA

链接到用户控件中的 FormA。

在用户控件中

#FormA

链接到用户控件中的 FormA,因为 ASP.NET 首先在用户控件本身内搜索。

在用户控件中

#FormB

链接到页上的 FormB,因为 ASP.NET 将窗体引用解析为相对于用户控件的父级。

创建移动用户控件时的特别注意事项

为移动应用程序开发用户控件时,必须考虑以下问题。

使用预定义样式

要使用户控件获得完全功能的样式支持,在创建移动用户控件时,必须在 .ascx 文件中从 MobileUserControl 类派生它们,而不是从标准的 UserControl 类派生。下面的代码示例演示这一情况。

<%@ Control Language="C#"
    Inherits="System.Web.UI.MobileControls.MobileUserControl" 
    %>
<%@ Register TagPrefix="mobile" 
    Namespace="System.Web.UI.MobileControls" 
    Assembly="System.Web.Mobile" %>

Web.config 文件的位置影响其使用

ASP.NET 使用当前运行页的目录来查找该页中控件的配置信息。因此,如果您在 Web.config 文件中定义了特定于设备的筛选器,该 Web.config 文件必须位于 ASP.NET Web 应用程序的移动网页一节的根目录。例如,如果您有一个名为 /Reports/Report1.aspx 的页,该页包含一个名为 /Sales/Inventory.ascx 的用户控件,而且您还有一个包含设备筛选器的 /Sales/Web.config 文件,则 /Sales/Inventory.ascx 控件将在 /Reports/Web.config 文件(而非 /Sales/Web.config 文件)中查找设备筛选器定义。

处理用户控件中的文本

将用户控件中的文本作为 LiteralControl 而不是 LiteralText 控件进行分析。如果用户控件包含文本,并且包含具有内部分页的控件(如 Form),则文本将显示在所有页上。为避免此问题,应将用户控件的内容放在 Panel 控件中,这样文本将由 ASP.NET 页框架分析并作为 LiteralText 控件处理。

请参见

参考

MobilePage

其他资源

创建自定义移动控件