【问题标题】:dynamic controls based on user postback基于用户回发的动态控制
【发布时间】:2011-01-23 11:26:53
【问题描述】:

假设我有一个树视图,其中每个树节点包含一组不同用户控件的 id。当用户点击一个节点时,这些控件应该被加载到页面中。据我了解 ASP 页面生命周期,应该在初始化阶段添加动态控件,稍后会触发回发事件。

那么如果treeview点击事件发生在我需要添加控件之后,如何根据用户回发事件动态添加控件呢?


编辑:我尝试了 ArronLS 的建议:

我所做的是将节点值添加到会话数组中,并在我执行初始化时使用它来选择将哪些表单元素加载到占位符控件的控件中。在树视图单击事件上,我更新会话数组中的节点,清除占位符中的旧表单元素,并将新的表单元素添加到控件中。当页面再次加载时,它现在应该在初始化时找到节点,因此可以避免视图状态问题。

现在我还没有完全测试这个,但是还有另一个similar post 讨论了视图状态可能导致的问题。他们提出了一种解决方案,该解决方案在 Init 控件中轮询上下文的 Request[] 部分(在他们的情况下为保管箱),手动处理一些回发功能。

我的新问题是如何使用请求数组访问树视图中的选定节点?

【问题讨论】:

    标签: c# asp.net event-handling dynamic-controls


    【解决方案1】:

    这可能不是您直接问题的答案,但由于我自己从未找到答案,因此这是我使用的解决方法。

    我在使用 TreeView 时一直使用的方法是在 aspx 页面中声明一次控件,然后在单击事件上,根据 id 将控件绑定到数据。如有必要,您可以最初将可见性设置为 visible="false" 并在绑定时更改它。这种方法效果很好,因为它避免了您所描述的难题。

    如果您不反对放弃树视图,nested repeater 方法也很有效。

    【讨论】:

    • 感谢您的建议。我有点犹豫每次都加载所有配置,因为我的树可以任意大,配置可能是唯一的,这可能会产生很大的开销。我以前从未使用过嵌套中继器,我会研究一下。
    【解决方案2】:

    未在 init 中加载控件的后果是,如果视图状态中的属性发生更改,这些将不会被持久化到控件中。例如,如果在页面的第一个请求中,您在 init 中动态创建控件,然后在回发时您在 init 中再次创建它们,然后在 init 之后,viewstate 中的任何属性值都将应用于控件。

    因此,如果您最初在树视图单击事件中创建控件,我猜应该没问题,因为自刚创建控件以来,还没有累积任何视图状态来应用到控件。但是,我不确定这是否会导致控件不保存视图状态。您必须对此进行试验。

    在第一次之后的后续回发中,现在您需要在 init 中创建控件以将累积的 viestate 应用于它,因此您需要一些机制来“记住”您之前创建过一次控件,最初是在响应单击事件,然后在随后的回发中再次在 init 中创建控件。如果您不知道,您必须在每个请求上重新创建控件。

    所以问题变成了控件的视图状态有多重要。

    编辑:我还要补充一点,除了这如何影响视图状态之外,我不完全确定是否会有其他后果。

    【讨论】:

    • 谢谢,我试试看。总结一下我认为您所说的是:第一次单击节点时,通过回发事件加载它并以某种方式持久化配置。然后,在后续的回发/页面加载中,在 init 函数中加载持久化节点。
    【解决方案3】:

    只是抛出一个想法,希望得到更多的反馈......

    我可以使用回发事件来定义会话数组中的选定值,然后强制页面重定向到自身。然后,用户看到的 init 将在事件处理程序触发后有效地完成。

    似乎是个坏主意,所以我希望有别的办法。

    【讨论】:

      【解决方案4】:

      如果我对您的理解正确,您希望为每个树节点显示不同的内容。 我假设左边是树视图,中间是一些内容区域。

      从 UI 的角度来看,我通常使用 MultiView 来解决这个问题,其中每个单独的 View 都是具有所需内容的单独用户控件。树节点点击事件只是改变了包含在节点值属性中的 MultiView ActiveIndex(ID 存储在 DataItem 中),您只需切换出内容区域。

      一般来说,即使树节点是动态生成的,例如从数据中,也只会有有限数量的“节点视图”用户控件需要定义。

      注意。使用 MultiView 控件时要小心,因为包含的所有视图都是在页面生命周期中加载的,因此不要将任何“繁重的”放入 Page_Load 等。

      【讨论】:

      【解决方案5】:

      记住所选节点的 ID 作为表单值传递可能会有所帮助,即使在 Init 事件期间,它也始终可以从 Request.Form 集合中访问。密钥类似于ctl00_Content1_TreeView1_SelectedNode。但是,仅此 ID 可能无法为您提供所需的值,因此您需要查看 Request.Form["__EVENTARGUMENT"] 并使用 Request.Form["__EVENTTARGET"] 来验证确实是 TreeView 导致了 PostBack。

      很可能您需要的信息可以从表单集合中提取出来。这只是设置断点并检查值的问题。这种代码总是让人觉得非常难懂,但在这种情况下,当您需要使用表单中提交的值在 Page_Init 期间执行某些操作时,您不能等待处理 TreeView 控件的事件。只是不要害怕查看表单值,而不是等待 .NET 将其与强类型属性很好地打包在一起。到那时就为时已晚。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-24
        • 1970-01-01
        • 2010-12-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多