从UpdatePanel以编程方式强制完全回发

时间:2011-10-31 17:16:19

标签: c# asp.net asp.net-ajax updatepanel

我在更新面板中有一个GridView。它是一个继承的asp:GridView,所以它有一个“导出我”的图标就是这样做的。它通过响应带有XLS文件的“导出”单击来工作。问题是,如果您将智能GridView放在更新面板中,ASP.NET认为XLS文件将写入面板,这显然不是我们想要的。为此,我每次都需要一个完整的回复。

我的更新面板都是以编程方式生成的

在这个精确的场景中无效的解决方案(其中很多都在SO的其他地方有所涉及):

  1. 在版本4之前的ASP.NET中,如果您将ID从控件中删除,它甚至可以在更新面板中执行完整的回发。我的问题是仅针对最新和最好的.NET 4。

  2. ScriptManager.RegisterPostBackControl看起来很有前途。它确实使控制后期使用正确的面板ID作为事件目标,但是没有其他帮助。

  3. 将PostBackTrigger添加到“更新”面板。我的更新面板是以编程方式生成的,MS声明不支持此更新。我的测试表明他们是对的:我尝试过各种方式,但这不起作用。

  4. 我真的不喜欢智能GridView不得不脱离自己的想法,但我试图让它在这些情况下在updatePanel之外添加一个额外的控件。通过客户端javascript重定向客户端单击面板内的导出按钮的想法,以模拟面板外部的该按钮的单击。但是这不起作用,因为我无法将“外部”控件添加到页面中 - 我得到“在DataBind,Init,Load,PreRender或Unload阶段无法修改控件集合”。错误。

  5. 使用jQuery将“导出”控件移到面板外部。 MS必须有一些他们认为在面板中的控件列表,并且DOM中的物理位置无关紧要。

  6. 有没有人有任何想法如何使这项工作?我知道很多应该工作,但这不是一回事。

4 个答案:

答案 0 :(得分:4)

对我来说,解决方案3有效。

我向页面动态添加UpdatePanel,向内容模板添加Button并关联PostBackTrigger。我添加了一个Click事件处理程序,在其中我使用当前日期/时间更新标签(在UpdatePanel之外)。

请参阅下面的测试设置。

<强>标记

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
<asp:Label ID="Label1" runat="server"></asp:Label>

代码背后

protected void Page_Load(object sender, EventArgs e)
{
    string buttonId = "Button1";

    UpdatePanel updatePanel = new UpdatePanel();
    updatePanel.ID = "UpdatePanel1";

    Button button = new Button();
    button.ID = "Button1";
    button.Text = "Post back";
    button.Click += new EventHandler(button_Click);

    updatePanel.Triggers.Add(new PostBackTrigger() { ControlID = buttonId});

    updatePanel.ContentTemplateContainer.Controls.Add(button);

    Panel1.Controls.Add(updatePanel);
}

void button_Click(object sender, EventArgs e)
{
    Label1.Text = string.Format("Current date/time: {0}", DateTime.Now.ToString());
}

希望这有帮助。

答案 1 :(得分:3)

我意识到这是在一年前被问到的,但如果它对其他人有帮助,那么解决方案2对我有用。

((ScriptManager)this.Page.Master.FindControl("scrptmgr")).RegisterPostBackControl(lnkbtn);

我可以让它工作的唯一方法是,当上面的代码行运行时,控件(在本例中为lnkbtn)是可见的。

编辑 - 经过更多测试后,现在似乎只有在注册控件以执行完整回发和实际点击事物之间没有回发时,此方法才有效。解决方案或hack是注册控件以在每个页面加载时执行完整的回发。

答案 2 :(得分:0)

我构建了一个类似的继承GridView控件,可以进行CSV导出。我处理它的方法是使导出按钮变为当前页面的简单<a href>,其中包含一个特制的查询字符串参数"?SortablePagableGridViewExportToCSV=XXX",其中XXX是我控件的UniqueID。我重写我的控件的Render方法,并在那里我手动检查请求参数,看看是否发送了导出参数。如果是这样,我会写下CSV内容类型标题和响应,如下所示。

Me.Page.Response.Clear()
Me.Page.Response.ClearContent()
Me.Page.Response.ClearHeaders()
Me.Page.Response.ContentType = "text/csv"
Me.Page.Response.AddHeader("Content-Disposition", "attachment;filename=" & Me.ExportToCsvFileName)
Me.Page.Response.End()

密钥是对Page.Response.End()的调用,它会停止所有进一步处理。这是一个GET请求所以我不必担心UpdatePanel asynch回发或类似的事情。在这种情况下,浏览器表现得非常漂亮,弹出下载链接,但保持用户在当前页面上。浏览器URL不会更改,用户甚至可以右键单击下载链接并使用目标另存为...如果愿意。

答案 3 :(得分:0)

如果应该强制页面回发的控件(假设一个按钮)是--inside--一个GridView模板字段,你可能在设置UpdatePanel触发器的controlId时遇到一些问题...在这种情况下你可以简单地去到teemplatefield按钮并将其“PostBackUrl”属性设置为......同一页面本身!

这样点击它就会强制完全回发......