基于用户回发的动态控制

发布于 2024-08-23 22:09:09 字数 617 浏览 7 评论 0原文

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

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


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

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

现在我还没有完全测试这一点,但还有另一个类似的帖子 讨论了视图状态可能导致的问题。他们提出了一种解决方案,在 Init 控件中轮询上下文的 Request[] 部分(在本例中为 dropbox),手动处理一些回发功能。

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

Suppose I have a treeview, where each treenode contains an id for a different set of user controls. When the user clicks a node, these controls should be loaded to the page. As I understand the ASP page life cycle, dynamic controls should be added in the initialization stage, and postback events will fire later on.

So if the treeview click event happens after I need to add my controls, how do I dynamically add controls based on user postback events?


Edit: I tried the suggestion from ArronLS:

What I did was add the node value to the session array, and use that when I do the init to choose which form elements to load to the controls of a placeholder control. On the treeview click event, I update the node in the session array, clear the old form elements in the placeholder, and add the new form elements to the controls. When the page is loaded again, it should now find the node at init time, so viewstate problems would be circumvented.

Now I haven't fully tested this yet, but there was another similar post that talks about the problems that might result with the viewstate. They suggest a solution that polls the Request[] part of the context (in their case the dropbox) within the Init control, manually handling some of the postback functionality.

My new question is how to I access the selected node in the treeview using the Request array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我一直都在从未离去 2024-08-30 22:09:09

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

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

如果您不反对放弃树视图,嵌套转发器方法也很有效。

This may not be an answer to your direct question, but since I've never found an answer myself, here's the workaround I've used.

The approach I've always used when working with a TreeView is to declare the controls in the aspx page once, and then on the click event, bind the controls the the data based on the id. If necessary, you can initially set the visibility to visible="false" and change it when bound. This approach works nicely because it avoids just the conundrum you're describing.

If you're not opposed to giving up on treeviews, a nested repeater approach works well, too.

牵强ㄟ 2024-08-30 22:09:09

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

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

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

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

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

The consequence of not loading the controls in init is that if there are changes to properties in the view state, these will not get persisted to the controls. For example, if on the first request of the page, you dynamically create controls in init, then on the post back you create them again in init, then after init, any property values in viewstate get applied to the control.

So if you created the control initially in a treeview click event, I would guess that should be fine, because there is not yet any viewstate accumulated to apply to the control since it was just created. However, I am not sure if this will cause the control to not save viewstate. You'd have to experiment with that.

On subsequent postbacks after the first, now you will need to create the control in init for accumulated viestate to be applied to it, so you'll need some mechanism to "remember" that you created the control once before, initially in response to the click event, and then on subsequent postbacks create the control again in init. You have to recreate the control on each request, if you didn't know that.

So the question becomes how important is the viewstate for the control.

Edit: I will also add that I am not entirely sure if there would be other consequence other than how this affects viewstate.

梦过后 2024-08-30 22:09:09

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

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

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

Just throwing out another thought, hoping to get some more feedback...

I could use the postback event to define the selected value in the session array, and then force the page to redirect to itself. Then, the init that the user sees will effectively be done after the event handler has fired.

Seems like a bad idea, so I'm hoping for something else.

猫九 2024-08-30 22:09:09

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

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

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

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

If I've understood you correctly you want different content shown for each tree node.
I'm assuming theres the treeview on the left and some content area in the middle.

From a UI perspective I normally solve this by using a MultiView where each individual View is a seperate usercontrol with the required content. The treenode click event simply changes the MultiView ActiveIndex contained in the Node value property (ID is stored in the DataItem) and you simply switch out the content area.

Generally, even if the tree nodes are dynamically generated, from data for example, there will only ever be a finite amount of "Node View" usercontrols that you need to define.

Note. Be careful when using the MultiView control as all Views contained are loaded during the page life-cycle so dont put any "heavy-lifting" into Page_Load etc.

南渊 2024-08-30 22:09:09

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

很可能您需要的信息可以从表单集合中提取。只需设置一个断点并检查值即可。这种代码总是让人感觉非常糟糕,但在这种情况下,当您需要使用表单中提交的值在 Page_Init 期间执行某些操作时,您就迫不及待地等待 TreeView 控件的事件被处理。只是不要害怕查看表单值,而不是等待 .NET 使用强类型属性将其全部打包。到那时就太晚了。

It may help to remember that the ID of the selected node is passed as a form value, which is always accessible from the Request.Form collection, even during the Init event. The key would be something like ctl00_Content1_TreeView1_SelectedNode. However, that ID alone would probably not get you the value you need, so you would want to look at Request.Form["__EVENTARGUMENT"] and also use Request.Form["__EVENTTARGET"] to verify that it was indeed the TreeView that caused the PostBack.

More than likely the information you need can be pulled out of the Form collection. It's just a matter of setting a breakpoint and examining the values. This kind of code always feels awfully hacky but in this case you just can't wait for the TreeView control's event to be handled when you need to use the values submitted in the form to do something during Page_Init. Just don't be afraid to look at the form values instead of waiting for .NET to package it all up nicely with strongly-typed properties. By then it will be too late.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文