Поднять OnMenuItemClick без ViewState?

У меня есть (производный) элемент управления Menu, который отображает довольно большой список элементов из настраиваемого источника данных. Мне нужно отключить ViewState в меню, чтобы избежать очень раздражающего сообщения «Невозможно выбрать отключенный или недоступный для выбора пункт меню», когда какой-либо другой элемент управления вызывает изменение текущего выбора при обратной передаче.

К сожалению, когда ViewState отключен для меню, обратные передачи, сгенерированные с помощью меню, не вызывают никаких событий. Если я включаю ViewState, возникает событие OnMenuItemClick. Если я отключу ViewState, OnMenuItemClick не появится. Я в недоумении.

Мне нужно отключить ViewState для меню, так как я могу обрабатывать обратные передачи из фактического меню?

На этом этапе я склоняюсь к использованию события Load в меню, разбирая __EVENTTARGET, чтобы увидеть, является ли оно меню, и перехожу оттуда. Технически это могло бы обработать событие обратной передачи раньше, чем обычно, но я думаю, это нормально.

Есть идеи получше?


person sliderhouserules    schedule 25.10.2008    source источник


Ответы (3)


Да, вы можете выбрать: либо использовать viewstate для повторного заполнения связанного элемента управления, либо привязать его к данным до запуска событий (Page_Load в порядке).

Я не обязательно всегда привязывать его заново в Page_PreRender, хотя, если в этой обратной передаче ничего не изменилось (изменения произошли где-то еще на странице), то нет причин для повторной привязки.

Вместо этого вы можете привязать только к определенным событиям, когда знаете, что их придется изменить.

person AndreasKnudsen    schedule 11.11.2008

Я разобрался в сути проблемы. Используя 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 я приказываю меню снова перестроить, чтобы оно отражало изменения, произошедшие во время обработки обратной передачи в жизненном цикле.

Я потратил на это много времени, поэтому надеюсь, что эта информация может помочь кому-нибудь еще в подобной ситуации.

person sliderhouserules    schedule 26.10.2008

В Page_Load повторно привяжите элемент управления к данным карты сайта и проверьте, есть ли IsPostBack.

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

это работает для меня и уменьшает состояние просмотра.

person Nicolò Beltrame    schedule 14.07.2014