【问题标题】:UserControl with UpdatePanel programmatically create ScriptManager possible?UserControl 与 UpdatePanel 以编程方式创建 ScriptManager 可能吗?
【发布时间】:2010-11-09 10:57:55
【问题描述】:

我想在我的 UserControl 中使用 UpdatePanel。问题是放置控件的 .aspx 页面将没有 ScriptManager。我需要在 UserControl 中创建 ScriptManager。但是,如果使用 UserControl,在页面上说两次,那么放置 ScriptManager 将不起作用,因为您只能初始化 ScriptManager 一次。

在我需要 ScriptManager 的其他用户控件中(我使用的是 AJAX 工具包扩展),我能够使用此代码:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    Page.Init += new EventHandler(Page_Init);
}

void Page_Init(object sender, EventArgs e)
{
    if (Page.Form != null && ScriptManager.GetCurrent(Page) == null)
        Page.Form.Controls.AddAt(0, new ScriptManager());
}

..效果很好,但不适用于 UpdatePanel 案例。

注意,我没有使用母版页

(我正在考虑但不知道该怎么做的另一种方法是在 UpdatePanel 中以编程方式创建 UserControl。)

【问题讨论】:

  • 只是一面没有,代码有点“双重”。您重写 OnInit 方法并添加一个 Init 事件处理程序。只需将 Page_Init 中的代码放在重写的 OnInit 中即可?

标签: asp.net ajax updatepanel user-controls scriptmanager


【解决方案1】:

我认为这是不可能的。我已经尝试了几种不同的方法。您可能不得不硬着头皮在页面中放置一个脚本管理器。

【讨论】:

    【解决方案2】:

    它不起作用的原因是什么?您是否从需要 ScriptManager 的 UpdatePanel 中获得异常?您使用的是 System.Web.Extensions 1.0 还是 3.5?我这么说是因为在 3.5 中对 UpdatePanel 进行了更改,导致其内容模板在 OnInit 之前实例化,所以我看不出有什么明显的原因导致它不起作用。如果出现异常,查看堆栈跟踪会很有帮助。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。问题是您需要在 OnInit 阶段之前添加脚本管理器 - 据我所知,它需要在 preinit 阶段完成。您可以通过添加大量覆盖来看到这一点 - 我发现页面通过了 preinit ok,然后进入了 addedcontrol 事件,它在(或之后,但这一点是有道理的)“你需要一个脚本管理器“被抛出。我正在努力寻找如何从子用户控件向 Page.PreInit 事件添加事件处理程序,因为 WUC 没有 PreInit 事件。甚至 WUC 构造函数在此之前也不会触发,并且在构造函数中页面对象为空,因此您无法将其添加到那里。即使在 WUC 的 AdditionalControl 阶段,您似乎仍然无法访问主页( ScriptManager oSCM = ScriptManager.GetCurrent(Page); 返回 null)因此您似乎无法添加脚本管理器,如果您需要,在抛出错误之前。

      /编辑:- 据我所见(我在 asp.net 论坛上对此没有任何回答 - 令人惊讶,令人惊讶)WUC 直到父级的预初始化阶段之后才开始启动它的方法/事件,所以有 2这样做的方法。

      1) 我认为我会这样做的方式是不要将任何内容放入需要脚本管理器的设计器中,并将占位符放置在需要放置此类内容的位置。然后在 wuc 加载中,您使用 ScriptManager.GetCurrent 查看是否已经存在一个,如果没有则创建它。然后动态添加需要 SCM 的内容。像这样的东西:-

      ----------------后面的代码--------------- 使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Web; 使用 System.Web.UI; 使用 System.Web.UI.WebControls; 公共部分类 wucTestExample : System.Web.UI.UserControl { protected void Page_Load(object sender, EventArgs e) { ScriptManager oSCM = ScriptManager.GetCurrent(this.Page); 如果(oSCM == null) { oSCM = new ScriptManager(); oSCM.ID = "scmAJAX"; oSCM.EnablePartialRendering = true; this.plcAJAX.Controls.AddAt(0, oSCM); } 更新面板 udpMain = 新的更新面板(); udpMain.ID = "udpMain"; 文本框 txtMain = new TextBox(); txtMain.ID = "txtMain"; // 这里的其他属性 按钮 btnPostback = new Button(); btnPostback.ID = "btnPostback"; btnPostback.Click += new EventHandler(btnPostback_Click); btnPostback.Text = "部分回发"; 标签 lblPostback = new Label(); lblPostback.ID = "lblPostback"; lblPostback.Text = "初始回发"; udpMain.ContentTemplateContainer.Controls.Add(txtMain); udpMain.ContentTemplateContainer.Controls.Add(btnPostback); udpMain.ContentTemplateContainer.Controls.Add(lblPostback); this.plcAJAX.Controls.Add(udpMain); } void btnPostback_Click(对象发送者,EventArgs e) { // 这里实现按钮代码 标签 lblPostback = (Label)this.plcAJAX.FindControl("lblPostback"); if (lblPostback != null) { lblPostback.Text = String.Format("WUC POstback at : {0}", DateTime.Now.ToLongTimeString()); } } }

      然后这样使用它:-

      内容> --%> 内容> ----------------后面的代码--------------- 使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Web; 使用 System.Web.UI; 使用 System.Web.UI.WebControls; 公共部分类 TestExampleNoSCM : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { this.lblLoadTime.Text = String.Format("页面加载时间:{0}",DateTime.Now.ToLongTimeString()); } }

      因此,如果您在父页面中评论或取消评论 SCM,WUC 仍然有效。

      2) 我看到另一个选项需要更新面板,程序员在设计器中创建了所有控件,然后在页面加载中循环它们(在创建 SCM 之后,如果需要,以及 UDP 并添加WUC UDP 上的所有控件,然后将其添加到占位符,但这让我觉得相当危险,因为它似乎是双重实例化控件,我认为它可能会回来咬他们...

      方法 1 的缺点是,以编程方式在更新面板中创建所有内容需要更多工作,但如果您真的想构建一个独立的 WUC,这似乎是您的代价(希望 WUC 不应该是无论如何,这很复杂)。就个人而言,我认为在我的应用程序中(因为 WUC 不会在它之外使用)我会确保在主页上需要的地方添加 SCM。

      另外一个,最后,请注意我会提出 - 我看到有人说“将它添加到母版页” - 这似乎是一个特别糟糕的主意,恕我直言,除非每个页面在您的应用程序中需要 SCM,因为它会为您的页面添加一个全新级别的膨胀,这似乎不是一个好主意,因为 ASP.NET 似乎已经有一个很好的膨胀级别......

      【讨论】:

      • 听起来你知道你在做什么!如果您找到解决方案,请告诉我!
      • 对我的上述编辑有一个警告,以编程方式添加控件可能会增加视图状态等方面的复杂性,所以我的工作就是向父级添加 SCM(也许在提到这一点的控件)可能是一个“更好”的选项,除非您需要该级别或自依赖/可移植性。
      【解决方案4】:

      如果页面上不存在 ScriptManager 而不是动态添加 ScriptManager,只需执行相反的操作:将 ScriptManager 添加到您的 ASCX 并在页面上已有 ScriptManager 时删除它。所以...

      protected override void OnInit(EventArgs e) {
          base.OnInit(e);
          AdjustScriptManager();
      }
      
      private void AdjustScriptManager() {
          if (ScriptManager.GetCurrent(Page) != null) {
              ScriptManager1 = null;
          }
      }
      

      更新:

      不,经过进一步测试,这将不起作用,因为 ScriptManager1 = null 没有任何帮助。如果有办法做到这一点(或删除 Page 控件),请发表评论。

      【讨论】:

        【解决方案5】:

        解决方案:可以通过检查当前页面是否尚未包含 ScriptManager 来在用户控件中动态添加脚本管理器。方法如下:)

        在 UserControl (ascx) html 中输入:

        <asp:PlaceHolder ID="pHolder" runat="server" />
        

        而在后面的代码(ascx.cs)中:

            //insert Scriptmanager dynamically only IF it does not already exist
             private void createScriptManager(System.EventArgs e)
            {
                // the GetCurrent() method will return a ScriptManager from the Page
                if (System.Web.UI.AjaxScriptManager.GetCurrent(this.Page) == null)
                {
                    System.Web.UI.AjaxScriptManager manager = new System.Web.UI.AjaxScriptManager();
                    manager.EnablePartialRendering = true;
                    pHolder.Controls.Add(manager);
                }
            }
        
            // call the above method from the usercontrol's OnInit
            override protected void OnInit(EventArgs e)
            {
                //
                // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                //
                createScriptManager(e);
                base.OnInit(e);
            }
        

        有时需要动态定义 ScriptManager。在我的情况下,我正在使用一个将被放入不同页面的用户控件,但是其中一些页面已经包含一个 ScriptManager 而有些则不包含,那么我的用户控件如何知道它是否应该定义自己的 ScriptManager?上述代码的美妙之处在于,用户控件仅在页面上还没有脚本管理器时才添加脚本管理器。

        注意:如果您使用旧版本的 Ajax,System.Web.UI.AjaxScriptManager 可能会替换为 System.Web.UI.ScriptManager。

        【讨论】:

        • 不起作用。当用户控件包含 UpdatePanel 时,如果页面上没有 ScriptManager,该控件甚至不会进入 OnInit。并且尝试在用户控件的构造函数中执行此操作将不起作用,因为 Page 将为 null。
        猜你喜欢
        • 2015-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多