【问题标题】:Raise OnMenuItemClick without ViewState?在没有 ViewState 的情况下提高 OnMenuItemClick?
【发布时间】:2008-10-25 05:38:20
【问题描述】:

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

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

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

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

有更好的想法吗?

【问题讨论】:

    标签: asp.net viewstate


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案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 期间,我告诉 Menu 再次重建,因此它反映了在生命周期的回发处理部分发生的更改。

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-18
          • 2018-12-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多