1

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

在我需要 ScriptManager 的其他 UserControls 中(我正在使用 AJAX Toolkit Extensions),我能够使用以下代码:

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。)

4

5 回答 5

0

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

于 2009-07-09T22:09:59.650 回答
0

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

于 2009-07-16T18:22:41.730 回答
0

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

/edit:- 据我所见(我在 asp.net 论坛上对此没有任何答案 - 令人惊讶,令人惊讶)WUC 直到父级的预初始化阶段之后才开始执行它的方法/事件,所以有两种方法可以做到这一点。

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

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="wucTestExample.ascx.cs" Inherits="wucTestExample" %>

<asp:PlaceHolder ID="plcAJAX" runat="server" />
<asp:Label ID="lblGeneral" runat="server" Text="这是另一个标签" />

----------------后面的代码---------------

使用系统;
使用 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());
        }
    }
}

然后这样使用它:-

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="TestExampleNoSCM.aspx.cs" Inherits="TestExampleNoSCM" %>
<%@ Register Src="~/wucTestExample.ascx" TagName="wucTestExample" TagPrefix="ucTE" %>

<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:内容>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <%--<asp:ScriptManager ID="scmAJAX" runat="server" />--%>
    <asp:标签 ID="lblLoadTime" runat="server" />
    <ucTE:wucTestExample ID="wucTestExample" runat="server" />
</asp:内容>

----------------后面的代码---------------

使用系统;
使用 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 似乎已经有了很好的膨胀程度......

于 2009-07-29T10:11:10.000 回答
0

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

protected override void OnInit(EventArgs e) {
    base.OnInit(e);
    AdjustScriptManager();
}

private void AdjustScriptManager() {
    if (ScriptManager.GetCurrent(Page) != null) {
        ScriptManager1 = null;
    }
}

更新:

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

于 2013-01-16T00:07:04.773 回答
-1

解决方案:可以通过检查当前页面是否还没有包含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。

于 2010-11-26T08:08:11.917 回答