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

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

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

此时我倾向于使用Menu的Load事件,解析__EVENTTARGET以查看它是否是菜单,并从那里开始。这在技术上会在正常情况下处理回发事件,但我认为没问题。

有更好的想法吗?

有帮助吗?

解决方案 2

我已经找到了问题的本质。使用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期间,我告诉菜单再次重建,因此它反映了生命周期的回发处理部分期间发生的更改。

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

其他提示

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

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

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

在Page_Load中将控件重新绑定到sitemapdata并检查IsPostBack。

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

这项工作对我来说并减少了观点状态。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top