【问题标题】:Reusable Page_PreRender function in asp.netasp.net 中可重用的 Page_PreRender 函数
【发布时间】:2010-09-04 12:27:45
【问题描述】:

我有一个函数可以将我的链接按钮设置为面板的默认按钮。

protected void Page_PreRender(object sender, EventArgs e)
    {
        string addClickFunctionScript = @"function addClickFunction(id) {
               var b = document.getElementById(id);
               if (b && typeof(b.click) == 'undefined')
                 b.click = function() {
                   var result = true;
                   if (b.onclick) result = b.onclick();
                   if (typeof(result) == 'undefined' || result)
                     eval(b.getAttribute('href'));
                 }
             };";

        string clickScript = String.Format("addClickFunction('{0}');", lbHello.ClientID);

        Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true);
        Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + lbHello.ClientID, clickScript, true);
    }

这很好用。如何使其可重用于我的应用程序的所有页面。一页可以有多个链接按钮和多个面板......任何建议......

【问题讨论】:

    标签: asp.net function reusability prerender


    【解决方案1】:

    最简洁的方法是使用继承自LinkButton 的自定义服务器控件。事实上,这似乎与您的earlier question 中的the blog post 一致。您需要做的就是覆盖OnPreRender 事件并粘贴您拥有的代码,同时将lbHello.ClientID 更改为this.ClientID 以引用该控件的特定实例。设置它的时间不应超过 10 分钟。完成此操作后,您可以在一个页面上使用任意数量的控件,并在应用程序的各个页面中轻松支持它。

    按照下面我的说明,特别是“创建服务器控件”部分:Walkthrough: Developing and Using a Custom Web Server Control 时,您可能会发现这篇 MSDN 文章很有帮助。以下是完成此操作的分步指南:

    1. 在您现有的解决方案中添加一个新的 ASP.NET 服务器控件项目(从解决方案资源管理器中右键单击您的解决方案 -> 添加新项目 -> ASP.NET 服务器控件)。将其命名为 LinkButtonDefault(当然,您可以随意更改名称)。
    2. ServerControl1.cs 重命名为LinkButtonDefault.cs
    3. 将文件中的命名空间重命名为CustomControls
    4. 通过打开AssemblyInfo.cs 文件(包含在项目的Properties 文件夹中)执行MSDN 文章中的步骤12-14。在文件底部添加这一行:[assembly: TagPrefix("CustomControls", "CC")]
    5. LinkButtonDefault.cs 中添加此代码以覆盖OnPreRender 事件:

    代码(注意使用this.ClientID):

        protected override void OnPreRender(EventArgs e)
        {
            string addClickFunctionScript = @"function addClickFunction(id) {
               var b = document.getElementById(id);
               if (b && typeof(b.click) == 'undefined')
                 b.click = function() {
                   var result = true;
                   if (b.onclick) result = b.onclick();
                   if (typeof(result) == 'undefined' || result)
                     eval(b.getAttribute('href'));
                 }
             };";
    
            string clickScript = String.Format("addClickFunction('{0}');", this.ClientID);
    
            Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true);
            Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + this.ClientID, clickScript, true);
    
            base.OnPreRender(e);
        }
    

    您可能还想更新以[ToolboxData("<{0}: 开头的类声明上方生成的属性代码,以使用LinkButtonDefault 而不是ServerControl1。这就是新的服务器控制项目。我强烈建议您阅读上述 MSDN 文章以利用其他功能,例如在需要时向工具箱添加控件。

    完成这些步骤后,您应该有一个类似于以下内容的LinkButtonDefault.cs 文件:

    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace CustomControls
    {
        [DefaultProperty("Text")]
        [ToolboxData("<{0}:LinkButtonDefault runat=server></{0}:LinkButtonDefault>")]
        public class LinkButtonDefault : LinkButton
        {
            [Bindable(true)]
            [Category("Appearance")]
            [DefaultValue("")]
            [Localizable(true)]
            public string Text
            {
                get
                {
                    String s = (String)ViewState["Text"];
                    return ((s == null) ? "[" + this.ID + "]" : s);
                }
    
                set
                {
                    ViewState["Text"] = value;
                }
            }
    
            protected override void RenderContents(HtmlTextWriter output)
            {
                output.Write(Text);
            }
    
            protected override void OnPreRender(EventArgs e)
            {
                string addClickFunctionScript = @"function addClickFunction(id) {
                   var b = document.getElementById(id);
                   if (b && typeof(b.click) == 'undefined')
                     b.click = function() {
                       var result = true;
                       if (b.onclick) result = b.onclick();
                       if (typeof(result) == 'undefined' || result)
                         eval(b.getAttribute('href'));
                     }
                 };";
    
                string clickScript = String.Format("addClickFunction('{0}');", this.ClientID);
    
                Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true);
                Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + this.ClientID, clickScript, true);
    
                base.OnPreRender(e);
            }
        }
    }
    

    现在返回到您的 Web 应用程序并添加对 CustomControls 项目的引用。您应该可以从添加引用的Project 选项卡中执行此操作,因为我建议将上述项目添加到您现有的解决方案中。如果您希望您可以在自己的解决方案中构建上述项目,那么您可以使用Browse 选项卡添加对它的.dll 文件的引用。添加引用后,您就可以使用新的LinkButtonDefault 控件了。

    要使用控件,您可以在将使用该控件的每个页面上使用@Register 指令,或者您可以将其添加到Web.config 并在整个应用程序中轻松引用它。我将在下面向您展示这两种方法。根据您的问题,我认为您需要将其添加到 Web.config 中。请参阅 MSDN 文章,您会在页面中间的“标签前缀”部分下找到此信息。

    使用@Register 指令:

    转到您想要的.aspx 页面并将Register 指令添加到您要在其中使用控件的每个页面的顶部:

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

    在同一页面上,您现在可以使用控件的多个实例。这是一个例子:

    <p><strong>1st Panel:</strong></p>
    <asp:Label runat="server" ID="helloLabel" />
    <asp:Panel ID="Panel1" runat="server" DefaultButton="lbHello">
        First name:
        <asp:TextBox runat="server" ID="txtFirstName" />
        <CC:LinkButtonDefault ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click"
            OnClientClick="alert('Hello, World!');" />
    </asp:Panel>
    
    <p><strong>2nd Panel:</strong></p>
    <asp:Label runat="server" ID="fooBarLabel" />
    <asp:Panel ID="Panel2" runat="server" DefaultButton="lbFooBar">
        Other:
        <asp:TextBox runat="server" ID="TextBox1" />
        <CC:LinkButtonDefault ID="lbFooBar" runat="server" Text="Click me" OnClick="lbFooBar_Click" />
    </asp:Panel>
    

    在 (.aspx.cs) 后面的代码中,您需要添加:

    protected void Page_Load(object sender, EventArgs e)
    {
        // example of adding onClick programmatically
        lbFooBar.Attributes.Add("onClick", "alert('Foo Bar!');"); 
    }
    
    protected void lbHello_Click(object sender, EventArgs e)
    {
        helloLabel.Text = String.Format("Hello, {0}", txtFirstName.Text);
    }
    
    protected void lbFooBar_Click(object sender, EventArgs e)
    {
        fooBarLabel.Text = String.Format("FooBar: {0}", TextBox1.Text);
    }
    

    使用 Web.config:

    要使用 Web.config,请保持与上面示例中使用的完全相同的标记和代码。请按以下步骤操作:

    1. 删除 .aspx 标记上使用的 @ Register 指令。
    2. 为您的 Web 应用程序打开 Web.config 文件。
    3. 找到&lt;system.web&gt;...&lt;/system.web&gt; 部分。
    4. 将以下映射添加到该部分:

    映射:

    <pages>
      <controls>
        <add assembly="CustomControls" namespace="CustomControls" tagPrefix="CC" />
      </controls>
    </pages>
    

    重新编译,一切都应该成功构建。有了这个,您不再需要在每个单独的页面上指定 @ Register 指令。

    如果您遇到问题并有任何问题,请告诉我。请仔细阅读以上所有内容,因为这是一篇包含大量代码的长篇文章。

    【讨论】:

      【解决方案2】:

      您可以创建一个派生自 System.Web.UI.Page 的类(我们称之为 Foo),并将您的方法抽象到可重用的程度。您所有的 ContentPages 都应该从 Foo 而不是 System.Web.UI.Page 派生

      【讨论】:

      • @citronas 如果我有多个链接按钮和多个面板,这将起作用
      • 这取决于您如何修改方法以使其正常工作。我只向您提供了有关如何在所有内容页面中轻松使用这种方法的信息。要获得对这些控件的引用,您可以在 this.Page.Controls 中递归搜索它们。
      【解决方案3】:

      我的建议是使用母版页,或者将代码分解为一个静态函数,该函数将 System.Web.UI.Page 对象作为参数。当然,您总是可以使用继承(这将起作用),但是您将失去使用拖放设计时功能来布局页面的能力,因为 VS.NET Web 表单设计器对 ASPX 页面做了一个很大的怪事不要直接从 System.Web.UI.Page 或 System.Web.UI.MasterPage 派生。

      【讨论】:

      • 如果我没记错的话,设计师有问题,那么这个问题是 VS2008 及以下版本。自从使用 VS2010 以来,我一直无法重现您的场景,因为它失去了设计时功能
      • 完全有可能。我承认我有一段时间没有构建 Web 表单了,即便如此,它也可能使用 VS2008。
      猜你喜欢
      • 2012-01-21
      • 2012-07-04
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-20
      相关资源
      最近更新 更多