Поднять OnMenuItemClick без ViewState?
Вопрос
У меня есть (производный) элемент управления Menu, который отображает довольно большой список элементов из пользовательского источника данных. Мне нужно отключить ViewState в меню, чтобы избежать очень раздражающего " Невозможно выбрать отключенный или невыбираемый элемент меню " когда какой-то другой элемент управления вызывает изменение текущей выборки при обратной передаче.
К сожалению, когда ViewState отключен для меню, обратные передачи, генерируемые посредством меню, не вызывают никаких событий. Если я включаю ViewState, возникает событие OnMenuItemClick. Если я отключаю ViewState, OnMenuItemClick не поднимается. Я в недоумении.
Мне нужно оставить ViewState выключенным для меню, так как я могу обрабатывать обратные вызовы из фактического меню?
На данный момент я склоняюсь к использованию события 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. Если вы не можете найти его в текущей коллекции Предметов, соответствующей входящим данным поста, событие не возникает. Если ViewState отключен, в меню нет элементов (они были бы перестроены с использованием ViewState). Таким образом, событие не будет возбуждено.
Чтобы обойти это, я сказал, чтобы меню создавалось во время загрузки с использованием еще не обновленных данных (на данный момент оно будет таким же, как в конце последнего запроса). По сути, это то же самое, что перестроить меню из ViewState, так что я не чувствую себя плохо в отношении производительности или чего-то еще. OnMenuItemClick тогда запускается как ожидалось. Наконец, во время PreRender я повторяю, что меню нужно перестроить, чтобы оно отражало изменения, произошедшие в течение части жизненного цикла обратной обработки.
Я потратил много времени на это, так что, надеюсь, эта информация может помочь кому-то еще в подобной ситуации.
Другие советы
Да, вы можете выбрать, либо использовать viewstate для повторного заполнения привязанного элемента управления, либо привязать данные к нему до запуска событий (Page_Load в порядке).
Я не всегда буду связывать его заново в Page_PreRender, хотя, если ничего не изменилось в этой обратной передаче (изменения произошли где-то еще на странице), то нет причин связывать его снова.
Вместо этого вы можете связываться только с определенными событиями, когда знаете, что их придется изменить. Р>
В Page_Load перепривязать элемент управления к карте сайта и проверить, есть ли IsPostBack.
if (IsPostBack) {
Menu.DataBind();
}
это работа для меня и уменьшение состояния.