Определите, был ли изменен выбранный индекс или было инициировано событие автопостбэка, в разделах кода программной части, отличных от обработчика событий.

У меня есть элемент управления ASP DropDownList со свойством AutoPostBack, для которого установлено значение true. Когда пользователь изменяет выбор, форма отправляет обратно, как и ожидалось. Я хочу знать, как определить в коде программной части, была ли страница отправлена ​​обратно по этой конкретной причине.


Я знаю, что могу определить такой обработчик событий...

protected void MyDropDownList_SelectedIndexChanged(object sender, EventArgs e) {
    // Run some code if the selection for the "MyDropDownList" control was changed
}

... но я хочу знать, как проверить, была ли форма отправлена ​​​​обратно, потому что выбранный индекс был изменен вне обработчика событий.

В частности, в методе Page_Load() у меня есть раздел if (IsPostback) {}, и я хочу, чтобы этот раздел не выполнялся, если обратная передача была вызвана изменением выбора в DropDownList. Итак, в псевдокоде я хочу что-то вроде:

if (IsPostback && (! <DropDownList's selection was changed, causing an autopostback>)) {

Я попытался определить глобальную логическую переменную и установить для нее значение true в обработчике событий, а затем проверить ее в Page_Load(), например так:

public partial class MyWebApp : System.Web.UI.Page {
    [...]
    static bool selectedIndexChanged = false;
    [...]
    protected void DomainDropDownList_SelectedIndexChanged(object sender, EventArgs e) {
        selectedIndexChanged = true; // Set this flag to true if selected index was changed
    }
    [...]
    protected void Page_Load(object sender, EventArgs e) {
    [...]
        if (IsPostBack && selectedIndexChanged == false) { 
            [...]
        }
        [...]

Это не сработало по причине, которую, как я полагаю, легко заметят опытные разработчики ASP.NET: обработчик событий выполняется после Page_Load(), независимо от порядка кода.

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

if (IsPostBack && !MyDropDownList.SelectedIndexChanged) {

но Visual Studio дает мне следующую ошибку:

Событие «System.Web.UI.WebControls.ListControl.SelectedIndexChanged» может отображаться только слева от += или -="

Поиск по сообщению об ошибке привел к этому ответу, но это, похоже, не помогает, поскольку он зависит от обработчика событий. , который выполняется после Page_Load().

В моем конкретном случае использования, когда есть только один DropDownList и только один другой способ отправки формы (кнопка отправки), было бы одинаково эффективно проверить, был ли изменен выбранный индекс, был ли запущен AutoPostBack или был ли была нажата кнопка отправки, но я также хотел бы знать, как это сделать в более широком диапазоне сценариев, например, если есть несколько элементов управления AutoPostBack и/или несколько способов отправки формы, кроме AutoPostBack.


Итак, мой вопрос разбивается следующим образом (хотя некоторые из них могут быть по сути одним и тем же вопросом, в зависимости от ответа):

  • Есть ли способ вообще определить, был ли запущен AutoPostBack, в отличие от отправки формы по любой другой причине, такой как нажатие кнопки?
  • Есть ли способ определить, был ли активирован AutoPostBack конкретного элемента управления (т. е. если есть несколько элементов управления с AutoPostBack true, можно ли определить, какой элемент управления вызвал AutoPostBack)?
  • Можно ли проверить в методе Page_Load() или любом другом коде, который выполняется перед обработчиком события SelectedIndexChanged, был ли изменен выбранный индекс DropDownList?

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


person Adi Inbar    schedule 01.06.2015    source источник
comment
Использовали ли вы инструменты отладки, чтобы посмотреть, что возвращается? Возможно, есть какое-то свойство запроса, которое вы можете использовать, и самый простой способ проверить это — посмотреть, что опубликовано.   -  person Guvante    schedule 02.06.2015
comment
Я не знаю, как это сделать, я новичок в ASP.NET и Visual Studio. Мне кажется, что это очень простая задача, и должен быть простой способ сделать это, но мне не удалось ни попытаться найти ее в Google, ни попытаться угадать ее.   -  person Adi Inbar    schedule 02.06.2015
comment
Найдите инструменты разработчика для используемого вами браузера, например, я использую Chrome и получаю доступ к инструментам через F12.   -  person Guvante    schedule 02.06.2015
comment
Вообще говоря, если вы можете положиться на события, вы все упростите. Другими словами, если вы сможете определить, что должно выполняться на Load, а что может обрабатываться управляющими событиями (после Load), то это облегчит вам жизнь. В противном случае ответ Мэтта ниже таков (также известный как проверка POST). Однако в какой-то момент, если у вас есть куча элементов управления, они станут громоздкими... Хм...   -  person EdSF    schedule 02.06.2015
comment
Я не уверен, как вы можете полагаться на события, если вы хотите, чтобы куча кода не выполнялась, если происходит определенное событие. Мне пришло в голову, что, поскольку в моем случае кнопка отправки в настоящее время является единственным другим способом отправить форму обратно, я могу просто переместить содержимое раздела `if (IsPostBack...) в обработчик событий для нажатия кнопки, так вот что я в итоге сделал. Однако сначала я попробовал решение Мэтта, и оно сработало. Так что это ответ, когда вы хотите, чтобы код выполнялся во всех случаях, кроме, когда срабатывает определенное событие.   -  person Adi Inbar    schedule 03.06.2015


Ответы (1)


Во время Page_Load осмотрите Page.Request.Form["__EVENTTARGET"]. Он будет содержать идентификатор, представляющий элемент управления, вызвавший отправку сообщения. Из этого вы сможете определить, была ли обратная отправка вызвана интересующим вас элементом управления.

if (IsPostBack && Request.Form["__EVENTTARGET"] != "<control ID>") {
    ...
}

Можно ли проверить в методе Page_Load() или любом другом коде, который выполняется перед обработчиком события SelectedIndexChanged, был ли изменен выбранный индекс DropDownList?

Не без обращения к нестандартной технике. Событие SelectedIndexChanged возникает слишком поздно во время жизненный цикл события страницы, чтобы быть полезным для вашего сценария. Один из вариантов — сохранить DropDownList.SelectedIndex в коллекции Page.ViewState во время Page.OnPreRender, а затем сравнить это значение с новым DropDownList.SelectedIndex в посте во время Page_Load.

person Matt Brooks    schedule 01.06.2015
comment
Спасибо, это помогает. Однако, что касается моего третьего пункта, есть ли способ проверить, был ли изменен выбранный индекс элемента управления вне обработчика событий? Может быть полезно в тех случаях, когда DropDownList не выполняет автопостбэк. Я предполагаю, что можно было бы использовать переменную ViewState, которая сохраняет текущий выбранный индекс в конце Page_Load(), а затем проверяет, отличается ли он в начале, но это кажется немного неуклюжим, есть ли прямой способ проверить, произошло ли конкретное событие в разделах кода программной части, кроме соответствующего обработчика событий? - person Adi Inbar; 03.06.2015
comment
Я обновил свой ответ, чтобы учесть ваш последний пункт. Надеюсь, это поможет. - person Matt Brooks; 03.06.2015