基于用户回发的动态控件

时间:2010-03-04 00:03:01

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

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

因此,如果在我需要添加控件后发生treeview click事件,如何根据用户回发事件动态添加控件?


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

我所做的是将节点值添加到会话数组中,并在我执行init时使用它来选择要加载到占位符控件的控件的表单元素。在treeview click事件中,我更新会话数组中的节点,清除占位符中的旧表单元素,并将新表单元素添加到控件中。当页面再次加载时,它现在应该在初始时找到该节点,因此可以规避viewstate问题。

现在我尚未对此进行全面测试,但还有另一个similar post讨论了viewstate可能带来的问题。他们建议一个解决方案,在Init控件中轮询上下文的Request []部分(在它们的情况下是dropbox),手动处理一些回发功能。

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

5 个答案:

答案 0 :(得分:1)

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

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

如果您不反对放弃树视图,nested repeater方法也适用。

答案 1 :(得分:0)

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

因此,如果您最初在树视图点击事件中创建了控件,我猜这应该没问题,因为自刚刚创建控件时,还没有任何视图状态可以应用于控件。但是,我不确定这是否会导致控件无法保存视图状态。你必须试验一下。

在第一个后面的回发之后,现在你需要在init中创建控件,以便将累积的viestate应用到它,所以你需要一些机制来“记住”你曾经创建过一次控件,最初是响应click事件,然后在后续回发中再次在init中创建控件。如果你不知道,你必须在每个请求上重新创建控件。

所以问题就在于控制的视图状态有多重要。

编辑:我还要补充一点,我不完全确定除了影响viewstate之外是否会有其他后果。

答案 2 :(得分:0)

抛弃另一个想法,希望得到更多反馈......

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

似乎是一个坏主意,所以我希望有别的东西。

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分:0)

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

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