Обработчик события вызывается только при втором нажатии - PullRequest
3 голосов
/ 08 мая 2009

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

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

Для информации: методы LoadViewWithAlphabeticalDatasource() и LoadViewWithWorkflowItem() делают то же самое, поэтому я удалил один из них в разделе ниже. События добавляются таким же образом.

Код:

<code><pre>
   namespace EPS.Web.View.Article
   {
       public class DynamicGridView : BasePage, IDynamicGridView
       {


           protected override void OnInit(EventArgs e)
           {
               Presenter = new DynamicGridPresenter(this);
               if (IsPostBack)
               {
                   if (Presenter.Step smallerthan 2)
                   {
                       LoadViewWithAlphabeticalDatasource();
                   }
                   else
                   {
                       LoadViewWithWorkflowItem();
                   }
               }
           }

           [PageMethod]
           protected void Page_Load(object sender, EventArgs e)
           {
               if(!IsPostBack)
               {
                   SetSubmenuVisible = false;
                   Presenter.InitView();
                   PrepareView();
               }
               AddEvents();
               AddLabels();
               PageMethodsEngine.InvokeMethod(this);
           }



           private void Back_Clicked(object sender, EventArgs e)
           {
               Presenter.StepEngine(DynamicGridPresenter.BACK, string.Empty, string.Empty);
               PrepareView();
           }

           private void Cancel_Clicked(object sender, EventArgs e)
           {
               Presenter.StepEngine(DynamicGridPresenter.CANCEL, string.Empty, string.Empty);
               PrepareView();
           }

           private void ForwardString(object sender, EventArgs e)
           {
               Presenter.StepEngine(DynamicGridPresenter.FORWARD, ((LinkButton)sender).CommandArgument, string.Empty);
               PrepareView();
           }

          private void ForwardWorkflowItem(object sender, EventArgs e)
          {
              Presenter.StepEngine(DynamicGridPresenter.FORWARD, string.Empty, ((LinkButton)sender).CommandArgument);
              PrepareView();
          }

          protected void PrepareView()
          {
              phDynamicGridView.Controls.Clear();
              if (Presenter.Step smallerthan 2)
              {
                  LoadViewWithAlphabeticalDatasource();
              }
              else
              {
                  LoadViewWithWorkflowItem();
              }
          }

          private void LoadViewWithWorkflowItem()
          {
              var table = new HtmlTable();
              table.Attributes.Add("class", "tableDynamicGrid");
              int max = GetRowLength(WODatasource.Count);
              int temp = 1;
              int actualPosition = 0;
              int itr = 1;
              var tr = new HtmlTableRow();

              if (WODatasource.Count == 0)
              {
                  phDynamicGridView.Controls.Add(new HtmlTable());
                  return;
              }

              foreach (WorkflowItem s in WODatasource)
              {
                  if (actualPosition biggerOrEqual MaxLength && temp smallerOrEqual max)
                  {
                      table.Rows.Add(tr);
                      actualPosition = 0;
                      temp++;
                      tr = new HtmlTableRow();
                  }


                  actualPosition++;

                  var cell = new HtmlTableCell();
                  // cell.Attributes.Add("class", "cellDynamicGrid");
                  var btn = new LinkButton
                                {
                                    CommandArgument = s.Oid.ToString(),
                                    Text = s.SelectionItem.Name /*, CssClass = "linkButtonDynamicGrid"*/
                                };
                  btn.Click += ForwardWorkflowItem;

                  cell.Controls.Add(btn);
                  tr.Cells.Add(cell);

                  if (itr == WODatasource.Count && temp smallerOrEqual max)
                  {
                      while (itr biggerOrEqual WODatasource.Count && itr smallerThan max*MaxLength)
                      {
                          tr.Cells.Add(new HtmlTableCell());
                          itr++;
                      }
                      table.Rows.Add(tr);
                      phDynamicGridView.Controls.Add(table);
                      return;
                  }
                  itr++;
              }
          }

       }
 

Ответы [ 5 ]

4 голосов
/ 08 мая 2009

OnInit происходит до того, как вызывается LoadPostData, и именно поэтому он, похоже, работает при втором щелчке. На самом деле происходит то, что вы обрабатываете событие из предыдущего постбэка.

  1. Page_Init
  2. LoadViewState
  3. LoadPostData
  4. Page_Load
  5. RaisePostDataChangedEvent
  6. RaisePostBackEvent
  7. Page_PreRender
  8. SaveViewState
  9. Page_Render
  10. Page_Unload

Это упрощенная версия событий из Asp.net 1.1; 2.0 имеет некоторые дополнительные события, вставленные между ними, такие как OnPreInit. Заказ остается, хотя.

Вы должны использовать событие из Load или позже. Некоторые люди выбирают PreRender, но соглашение для DataBinding находится в Load.

UPDATE

Я вижу, вы динамически добавляете элементы управления в дерево элементов управления. Это чревато подводными камнями (но вполне выполнимо).

a) убедитесь, что вы добавляете динамические элементы управления КАЖДЫЙ раз при загрузке страницы, а не только при обратной передаче. Postback / viewstate сохраняется STATE (т.е. данные), а не объекты. Вы должны добавить их в OnInit (OnLoad тоже работает, но поддерживать его сложнее). В настоящее время вы добавляете только постбэк, поэтому работает 2-й постбэк (а не первый)

b) инициализировать динамические элементы управления ТОЛЬКО ОДИН РАЗ, как и любой другой элемент управления - на [! IsPostBack], в Load.

-Oisin

3 голосов
/ 11 мая 2009

Спасибо всем, кто помог мне. Я нашел решение:

Я не знал, что динамически создаваемая кнопка нуждается в значении идентификатора. Я предложил Аспу знать, какая кнопка создана. К сожалению, я был неправ. Похоже, что .NET сравнивает идентификатор на кнопках, а не позицию в ControlTree.

Я добавил

new Button{ID = itr.ToString()}

Теперь, когда сервер перестраивает сайт, запускается обработчик событий.

С уважением х.

1 голос
/ 08 мая 2009

Проблемы такого рода почти всегда являются результатом подключения обработчиков событий в неправильном месте в жизненном цикле страницы.

0 голосов
/ 13 февраля 2017

если вы используете переменную ID без объявления, это может быть причиной проблемы. измените имя вашей переменной ID имя.

0 голосов
/ 25 сентября 2009

У меня просто была похожая проблема. Я перепробовал множество решений, но в итоге заметил, что одно из текстовых полей в моей веб-форме отправляло сообщения обратно на сервер, что приводило к ошибкам. Это была трудная ошибка, чтобы поймать, потому что я не хотел, чтобы мое текстовое поле делало это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...