我有一个我认为应该是相当简单的问题,但就我的一生而言,我看不到我的问题.这个问题与ScriptManager有关.RegisterStartupScript,我以前使用过很多次.

我的场景是,我有一个自定义的web控件,该控件已插入到页面中.该控件(以及一个或两个其他控件)嵌套在UpdatePanel中.它们被插入到页面的占位符上:

<asp:UpdatePanel ID="pnlAjax" runat="server">
  <ContentTemplate>
    <asp:PlaceHolder ID="placeholder" runat="server">
    </asp:PlaceHolder>
    ...

protected override void OnInit(EventArgs e){
  placeholder.Controls.Add(Factory.CreateControl());
  base.OnInit(e);
}

这是页面上唯一的更新面板.

该控件需要运行一些初始javascript才能正常工作.控件调用:

ScriptManager.RegisterStartupScript(this, GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

我也try 过:

ScriptManager.RegisterStartupScript(Page, Page.GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

问题在于,第一次显示页面时脚本运行正常,但在部分回发后不会重新运行.我try 了以下方法:

  1. 从CreateChildControls调用RegisterStartupScript
  2. 从onLoad/OnPreRender调用RegisterStartupScript
  3. 对前两个参数使用不同的参数组合(在上面的示例中,Control是Page,Type是GetType(),但我try 使用控件本身,依此类推).
  4. 我已经try 使用永久ID和新ID(我并不认为这两种方式都会产生重大影响).
  5. 我使用了几个断点,因此验证了寄存器行是否被正确调用.

我唯一没有try 的是使用UpdatePanel本身作为Control和Type,因为我认为控件不应该知道更新面板(而且无论如何,似乎没有获得更新面板的好方法?).

有没有人看到我在上面可能做错了什么?

谢谢:)


好吧,为了回答上面的问题,占位符似乎确实搞乱了ScriptManager.RegisterStartupScript.

当我将控件从占位符中拉出并将其直接编码到页面上时,Register脚本可以正常工作(我还将控件本身用作参数).


ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(), script, true);

有人能解释一下为什么在占位符上注入控件会阻止ScriptManager正确注册脚本吗?我猜这可能与动态控件的生命周期有关,但是(据我所知)如果有一个正确的过程来处理上述问题,我将不胜感激.

推荐答案

我认为您确实应该使用RegisterStartupScript的Control overload.

我在服务器控件中try 了以下代码:

[ToolboxData("<{0}:AlertControl runat=server></{0}:AlertControl>")]
public class AlertControl : Control{
    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        string script = "alert(\"Hello!\");";
        ScriptManager.RegisterStartupScript(this, GetType(), 
                      "ServerControlScript", script, true);
    }
}

在我的页面中,我有:

protected override void OnInit(EventArgs e){
    base.OnInit(e);
    Placeholder1.Controls.Add(new AlertControl());
}

其中Placeholder1是更新面板中的占位符.占位符中还有几个其他控件,包括按钮.

这完全符合您的预期,每次我加载页面或导致更新面板更新时,都会收到一个警告,说"Hello".

您可以查看的另一件事是连接到更新面板请求期间触发的一些页面生命周期事件:

Sys.WebForms.PageRequestManager.getInstance()
   .add_endRequest(EndRequestHandler);

每次更新面板完成更新时都会触发PageRequestManager endRequestHandler事件,这将允许您调用一个方法来设置控件.

我唯一的其他问题是:

  • 你的 playbook 到底在做什么?
  • 您大概可以在页面底部的HTML中看到脚本(就在关闭<;/form>;标记之前)?
  • 你有没有试过放几句"警告("这里");"调用你的启动脚本,看看它是否被正确调用?
  • 你试过Firefox和Firebug了吗--有没有报告任何脚本错误?

Asp.net相关问答推荐

DataTables-如何修改来自JSON响应或其他DataTables参数的无结果(ZeroRecords)消息

$(document).ready 不工作

如何在现有数据库中创建 ASP.Net Identity 表?

如何在 C# 中生成一个随机的 10 位数字?

任何人都有解决 Internet Explorer 上剩余 n 项问题的 idea 吗?

在哪里可以记录 ASP.NET Core 应用程序的启动/停止/错误事件?

在 appSettings 中存储字符串数组?

说服遗留应用程序 VB6 开发人员切换到 C#

未知的网络方法.参数名称:methodName

如何将 Castle Windsor 与 ASP.Net Web 表单一起使用?

将复选框的值传递给 asp.net mvc4 中的控制器操作

如何在 Visual Studio 2017 中使用 NPM 并安装包?

Devexpress 或 Telerik Controls 比较

为什么对 ASP.NET MVC 控制器的调用不执行 DelegatingHandler?

ASP.NET 中的全局资源与本地资源

Web.Config 中的 Assemblies node 的用途是什么?

如何在 ASP.Net Gridview 中添加确认删除选项?

路由模板分隔符/不能连续出现 - 属性路由问题

IISExpress 找不到使用 Visual Studio 2013 运行 localhost 的 ssl 页面

Application_End global.asax