65.9K
CodeProject 正在变化。 阅读更多。
Home

使用自定义 HTML 属性扩展 ASP.NET Web 控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (32投票s)

2005年4月13日

4分钟阅读

viewsIcon

239701

downloadIcon

2093

利用 ASP.NET 的现有功能来扩展框架的 Web 控件。

Sample Image - main.jpg

引言

您是否曾编写代码为现有的 ASP.NET 控件实现自定义功能(文本格式化、权限检查等)? 您可以通过实现自定义 Web 控件来实现这些定制,但是,如果能为现有的 ASP.NET 控件应用额外的属性来实现相同的结果,那岂不是更好? 本文将介绍一种利用 ASP.NET 的现有功能,通过应用自己的自定义 HTML 属性来扩展现有 Web 控件的方法。

快速背景介绍

要理解此扩展功能,必须熟悉 ASP.NET 的生命周期,特别是 System.Web.UI.Page 创建其子控件的方式。 如果查看 Page 的对象层次结构,您会发现它直接继承自 System.Web.UI.TemplateControl,而后者又继承自 System.Web.UI.ControlControl 类定义了受保护的虚拟方法 CreateChildControls,该方法用于通知服务器控件创建任何包含的子控件,为回发或呈现做准备。 要实现此方法的我们自己的版本,我们需要创建继承自 System.Web.UI.Page 的自己的类。

创建一个简单的自定义页面

要实现一个简单的 ASP.NET 基类页面,请定义一个继承自 System.Web.UI.Page 的新类。

public class BasePage : System.Web.UI.Page { ... }

接下来,我们需要重写 CreateChildControls 方法来指定我们自己的控件创建逻辑。

 protected override void CreateChildControls() { ... } 

由于所有 Web 控件和用户控件都必须位于 HTML 表单中才能工作,因此我们需要做两件事:

  1. CreateChildControls 中,遍历所有“页面”控件,并找到类型为 System.Web.UI.HtmlControls.HtmlForm 的控件。
  2. 遍历表单控件内的控件,并选择所有类型为 System.Web.UI.WebControls.WebControl 的控件。

以下代码定义了此发现过程:

/// <summary>
/// Overrides the common functionality for the creation
/// of controls within the page.
/// </summary>
protected override void CreateChildControls()
{
    // Find the form control in which all asp.net (or custom) controls
    // must be hosted.
    foreach (Control c in this.Controls)
    {
        if (c is System.Web.UI.HtmlControls.HtmlForm)
        {
            ProcessForm(c as HtmlForm);
        }
    }

    // Call the base implementation
    base.CreateChildControls();
}

/// <summary>
/// Process each of the controls within the form
/// </summary>
/// <param name="form">The html form for the page</param>
private void ProcessForm(HtmlForm form)
{
    // Find all the web controls, ie <asp:control_name />, and
    // check process them.
    //
    // You can also add logic here to check for user controls or 
    // custom user controls.
    foreach (Control cc in form.Controls)
    {
        if (cc is WebControl)
        {
            // Once you find the a web control, process any 
            // custom attributes you have specified.
            AttributeParser.ProcessControl(cc as WebControl);
        }
    }
}

现在我们有了基类页面并定义了发现过程,我们可以借助一些额外的类来开始处理我们的自定义属性。

代码逐步解析

用于发现自定义 HTML 属性的主要类是 AttributeParser 类。 此类包含一个名为 ProcessWebControl 的方法,该方法简单地遍历所有先前定义的属性(由 AttributeType 枚举表示),并检查每个 Web 控件的属性是否匹配。 如果找到匹配项,则 AttributeType 将与 AttributeFactory 类结合使用,以获取实现 IAttribute 接口的类的实例。 使用此类的实例,我们然后调用 IAttribute.Apply 方法,并将属性的值连同定义该属性的控件一起传递。 这将允许实现类根据自定义 HTML 属性的值对 Web 控件执行任何自定义操作。

以下是代码的快速预览:

/// <summary>
/// Processes the control's custom attributes.
/// </summary>
/// <param name="control">Current web control being rendered.</param>
public static void ProcessControl(WebControl control)
{
    foreach(string attribute in Attributes)
    {
        // Get the value of the custom attributes
        string attributeValue = control.Attributes[attribute];

        // If the custom attribute is defined, process it
        if (attributeValue != null)
        {
            // Get the attribute's type
            AttributeType at = (AttributeType)Enum.Parse(typeof(AttributeType), 
                                attribute, true);

            // Get the class to process the custom attribute
            IAttribute customAttribute = AttributeFactory.GetAttribute(at);

            if (customAttribute != null)
            {
                // Apply the attribute for the control
                customAttribute.Apply(attributeValue, control);
            }
        }
    }
}

实现 IAttribute 接口的两个类是 PermissionAttribute 类和 TextStyleAttribute 类。 PermissionAttribute 类用于对包含 permission HTML 属性的 Web 控件应用声明性安全。 换句话说,如果 TextBox 控件在其 HTML 中定义了 permission 属性,那么 TextBox 将对定义的角色列表启用;否则,该控件将被禁用。

<asp:textbox id="txtData" runat="server" permission="Administrators">INFO</asp:textbox>

如果 HttpContext.User 不属于 Administrator 角色,则 TextBox 的外观如下:

Disabled textbox using the permission custom HTML attribute

TextStyleAttribute 类用于为 TextBox Web 控件应用自定义的外观和感觉。 对于本文,我实现了一种电话样式,该样式借助 JavaScript 在您键入时将文本格式化为电话号码。 要启用此自定义样式,您需要将 textstyle 自定义 HTML 属性应用于您的文本框。

<asp:textbox id="txtPhone" runat="server" textstyle="phone" />

当您在 TextBox 中输入数字时,此 TextBox 将自动在区号、前缀和后缀之间添加“-”。

Applies custom javascript aid the formatting of the entered phone number.

TextStyleAttribute 类与 PermissionAttribute 类的实现方式略有不同,它使用自定义属性的值来在自定义 HTML 属性中进一步定义自定义操作。 这允许您为 TextBox 实现不同的样式。 例如,您可以定义一个日期 textstyle,它会自动将输入的数字格式化为简单的日期(mm/dd/yyyy)。 TextStyleAttribute 类实现如下:

/// <summary>
/// Summary description for TextStyleAttribute.
/// 
/// Contains the custom implementation for processing the style type
/// for a System.Web.UI.WebControls.TextBox.
/// </summary>
public class TextStyleAttribute : IAttribute
{
    #region IAttribute Members

    /// <summary>
    /// Applies the specified style to the web control.
    /// </summary>
    /// <param name="attributeValue">The style used for the rendered control</param>
    /// <param name="wc">The current control</param>
    public void Apply(string attributeValue, WebControl wc)
    {
        // Perform only if the control is a text box
        if (wc is TextBox)
        {
            // Get the style to apply for the text box
            TextStyle mode = (TextStyle)Enum.Parse(typeof(TextStyle), 
                            attributeValue, true);

            // Apply the specific style
            switch(mode)
            {
                case TextStyle.Phone:
                    PhoneStyle(wc as TextBox);
                    break;
                
                // Add more styles here.
            }
        }
    }

    #endregion

    /// <summary>
    /// Applies the 'Phone' style to the text box (ddd-ddd-dddd)
    /// </summary>
    /// <param name="text">Current TextBox control</param>
    private void PhoneStyle(TextBox text)
    {
        // Add custom javascript
        text.Attributes.Add("onKeyUp", "javascript:AutoPhone(this)");
        
        // Set the max size for a phone number
        text.MaxLength = 12;
    }
}

有关所使用的类的更多信息,请参阅随附的源代码。

结论

所呈现的两个属性实现旨在展示扩展 ASP.NET 附带的当前控件有多么容易,并为您创建自己的自定义 HTML 属性提供一个良好的开端。 如果您当前拥有自定义 ASP.NET 框架,添加此类功能将使您的框架更具可定制性。

请随时在下方留下任何评论。

© . All rights reserved.