我有一个(派生的)Menu控件,它显示来自自定义数据源的相当大的项目列表。我需要在菜单上禁用ViewState以避免非常烦人的“无法选择禁用或不可选择的菜单项”,当某些其他控件导致当前选择在回发时更改时。
不幸的是,当为菜单禁用ViewState时,按菜单生成的回发不会引发任何事件。如果我启用ViewState,则引发OnMenuItemClick事件。如果我禁用ViewState,则不会引发OnMenuItemClick。我很困惑。
我需要关闭ViewState菜单,那么如何处理实际菜单中的回发?
此时我倾向于使用Menu的Load事件,解析__EVENTTARGET以查看它是否是菜单,并从那里开始。这在技术上会在正常情况下处理回发事件,但我认为没问题。
有更好的想法吗?
答案 0 :(得分:1)
是的,您可以选择使用viewstate重新填充绑定控件,也可以在触发事件之前对其进行数据绑定(Page_Load很好)。
我不一定总是在Page_PreRender中重新绑定它,如果此回发没有任何改变(更改发生在页面上的其他地方),那么没有理由再次绑定它。
相反,当您知道必须更改时,您可能只能绑定某些事件。
答案 1 :(得分: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期间,我告诉菜单再次重建,因此它反映了生命周期的回发处理部分期间发生的更改。
我浪费了很多时间,所以希望这些信息可以帮助处于类似情况的其他人。
答案 2 :(得分:0)
在Page_Load中将控件重新绑定到sitemapdata并检查IsPostBack。
if (IsPostBack) {
Menu.DataBind();
}
这项工作对我来说并减少了观点状态。