2

我有一个(派生的)菜单控件,它显示来自自定义数据源的相当大的项目列表。我需要在菜单上禁用 ViewState 以避免在某些其他控件导致当前选择在回发时更改时非常烦人的“无法选择禁用或不可选择的菜单项”。

不幸的是,当菜单的 ViewState 被禁用时,菜单生成的回不会引发任何事件。如果我启用 ViewState,则会引发 OnMenuItemClick 事件。如果我禁用 ViewState,则不会引发 OnMenuItemClick。我很困惑。

我需要为菜单关闭 ViewState,那么如何处理来自实际菜单的回发?

在这一点上,我倾向于使用菜单的加载事件,解析 __EVENTTARGET 以查看它是否是菜单,然后从那里开始。从技术上讲,这将在正常情况下处理回发事件,但这没关系,我猜。

有更好的想法吗?

4

3 回答 3

1

是的,您可以选择使用视图状态重新填充绑定控件,或者您可以在事件触发之前对其进行数据绑定(Page_Load 很好)。

不过,我不一定总是在 Page_PreRender 中重新绑定它,如果此回发没有任何更改(更改发生在页面上的其他地方),则没有理由再次绑定它。

相反,当您知道必须更改时,您可能只能绑定某些事件。

于 2008-11-11T09:06:02.617 回答
0

我已经弄清楚了问题的本质。使用 Reflector 我们可以看到处理实际回发然后引发事件的低级方法的重要部分:

string str = HttpUtility.HtmlDecode(eventArgument);
...
MenuItem item = this.Items.FindItem(str.Split(new char[] { '\\' }), 0);
if (item != null)
    this.OnMenuItemClick(new MenuEventArgs(item));

如您所见,MenuEventArgs 被交给了一个 MenuItem。如果在当前的 Items 集合中找不到与传入的帖子数据匹配的对象,则不会引发该事件。禁用 ViewState 后,菜单没有任何项目(它们将使用 ViewState 重建)。所以不会引发事件。

为了解决这个问题,我已经告诉菜单在加载期间使用尚未更新的数据构建自己(此时它将与上次请求结束时相同)。这与从 ViewState 重建菜单基本相同,因此我对性能或其他方面的感觉并不差。OnMenuItemClick 然后按预期触发。最后,在 PreRender 期间,我告诉 Menu 再次重建,因此它反映了在生命周期的回发处理部分发生的更改。

我在这上面浪费了很多时间,所以希望这些信息可以帮助处于类似情况的其他人。

于 2008-10-26T03:40:19.523 回答
0

在 Page_Load 中将控件重新绑定到站点地图数据并检查是否为 IsPostBack。

if (IsPostBack) {
            Menu.DataBind();
}

这对我有用并减少了视图状态。

于 2014-07-14T20:33:34.207 回答