处理多个"链接"来自单个页面中动态创建的控件的回发

时间:2015-01-21 21:35:18

标签: c# asp.net webforms event-handling postback

我正在尝试为项目构建一个非常具体的搜索页面,并且我在处理由单个页面上动态生成的控件调用的多个回发时遇到了很多麻烦。

页面必须像这样工作:

  • 只有一个复选框"详细搜索" ,会导致检查/取消选中回发。

    • 当详细搜索未激活时,将显示包含内容和按钮的简单网格。没什么特别的。

    • 当详细搜索处于活动状态时,必须从某些动态数据生成 N 复选框,这些数据代表您希望搜索发生的部分。在复选框下方,将出现一个支持AJAX的选项卡控件,最初没有标签页。

      • 选中其中一个部分复选框时,将发生回发。在回发之后,将在用户选择的部分中搜索数据,然后将包含网格视图结果的新选项卡页面以及该部分的名称添加到选项卡控件中。如果取消选中该复选框,则在回发后,标签页将再次从控件中消失。

现在,问题在于,几乎所有东西都必须动态生成,而且几乎所有内容都与其他内容相关联。

第一个问题:处理"详细搜索" 复选框。听起来很简单,不是吗?我最初的想法是在检查/取消选中事件处理程序期间将Page.Viewstate["DetailedSearchEnabled"]设置为truefalse,然后在DetailedSearchEnabled期间创建控件以动态检查Page_Load的值。

没有。回发事件处理发生在Page_LoadPage_LoadComplete之间。这需要额外刷新才能使事情按预期工作。

<<然后我就会在Page_LoadComplete上生成控件! >>

没有。这些控件也需要事件处理,如果它们在Page_Load之后生成,则它们将无法正确连接。

一种可能的解决方案是在Page_Load上提前生成所有内容,并且只隐藏/显示Page_LoadComplete上的控件。但这是低效的,此搜索页面的一个重点是只应生成最少量的控件。

此任务的难度似乎来自事件布线和页面生命周期的工作方式。

当然必须有更好的方法来解决这个问题。

5 个答案:

答案 0 :(得分:1)

  

第一期:处理“详细搜索”复选框。

正确的方法(如果您想使用页面回发)如下:

  • 在CheckChanged事件处理程序中,将Checked属性的值保存到ViewState["DetailedSearchEnabled"]。如果值为true,则将动态复选框添加到页面。如果值为false,请查找并删除它们。
  • 覆盖LoadViewState。调用base.LoadViewState后,重新创建动态复选框,并在ViewState["DetailedSearchEnabled"]为真时将其事件连接起来。请注意,Page_Load和Page_LoadComplete都不适合这样做。

是的,您应该在页面生命周期的两个点创建动态复选框。我推荐一种辅助方法。

通常,您的事件处理程序应仅添加或删除受这些特定事件影响的动态控件(如果有),但LoadViewState应重新创建所有动态控件,这些控件存在于上一页请求中。您必须在视图状态中为LoadViewState存储足够的信息才能执行此操作。

我对this other question的回答演示了如何添加和删除动态控件。您可能希望将其用作参考。

答案 1 :(得分:0)

听起来我应该使用CheckBoxList控件来处理动态复选框。您可以在回发期间向CheckBoxList添加删除项目,而不必担心动态添加/删除表单中的实际控件/事件。

这是msdn的链接: https://msdn.microsoft.com/en-us/library/14atsyf5(v=vs.85).aspx

以下是一些示例代码:

Protected void Button1_Click (object sender, System.EventArgs e)
{
    CheckBoxList.Items.Add(new ListItem("TextValue1", "Value1"));
    CheckBoxList.Items.Add(new ListItem("TextValue2", "Value2"));
}

答案 2 :(得分:0)

如果所有其他方法都失败了,你仍然可以依靠快速而肮脏的老式ASP方式。

  • 使用Response.Write<%...%>生成动态控件作为普通旧HTML(简单表单字段,例如<input type="checkbox" name="foo" value="1" />)。
  • 确保在回发后您可能需要每条信息的表单字段。如有必要,请使用隐藏的表单字段在后续回发中“重新发布”值。
  • 回发后,使用Request对象检索控件的值。
  • 使用这些值根据需要调整控件的生成。

您应该可以在Page_Load中执行所有这些操作。优点是完全自由。缺点是完全自由地使你的aspx乱七八糟。所以你可能想要将所有这些脏代码从你的aspx迁移到一个定制的控件中,然后你可以将它添加到你的aspx中。

生成自己的HTML时,请注意不要引入XSS漏洞。必要时使用HtmlEncode。

答案 3 :(得分:0)

最好使用jquery和ajax调用来根据需要加载控件,然后将事件附加到它,或者甚至可以使用UpdatePnael。帮助链接:

https://www.simple-talk.com/dotnet/asp.net/ajax-basics-with-jquery-in-asp.net/ http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/

答案 4 :(得分:0)

正如你自己建议的那样,有一种更好的方法可以解决它。

如果我处于相同的情况,我会创建用于与页面交互的Web方法,并使用客户端来执行UI。我目前主要使用角度JS,虽然它确实带有学习曲线。您可以使用ng-hide / ng-show绑定到checkbox事件以显示详细搜索。当需要显示n个复选框时,您可以使用ng-repeat填充它们,对于您需要显示的每个项目,在检查/取消选中后,您可以通过Web方法调用动态填充新控件等。如果需要额外的数据。

从我的经验来看,纯ASP回发非常笨拙,并不适合构建可维护的动态UI。