asp.net - 仅在第二次单击时调用事件处理程序

标签 asp.net event-handling

我正在构建一个动态按钮 View ,它根据数据库中的项目数量以编程方式添加按钮。就像一个简单的工作流引擎。在第一页调用时,事件处理程序按预期工作。包含新项目的新页面被构建并返回给客户端。在第二次回发时,不会调用事件处理程序,并且 View 保留相同的项目。通过重新单击同一按钮(第三次回发),将触发事件处理程序中的断点。

我的问题是,为什么即使我在每次回发时重建页面(覆盖 OnInit()),事件处理程序也不会被调用?

信息:方法 LoadViewWithAlphabeticalDatasource()LoadViewWithWorkflowItem() 的作用完全相同,因此我在下面的部分中删除了一个。事件以相同的方式添加。

代码:

<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++;
              }
          }

       }
 </pre>

最佳答案

OnInit 发生在调用 LoadPostData 之前,这就是它在第二次单击时起作用的原因。实际发生的情况是您正在处理先前回发的事件。

  1. Page_Init
  2. 加载 View 状态
  3. 加载PostData
  4. 页面加载
  5. RaisePostDataChangedEvent
  6. RaisePostBackEvent
  7. 页面预渲染
  8. 保存 View 状态
  9. 页面渲染
  10. Page_UnLoad

这是来自 Asp.net 1.1 的事件的简化版本; 2.0 在其间插入了一些额外的事件,例如 OnPreInit。但顺序仍然保留。

您必须使用来自 Load 或更高版本的事件。有些人选择 PreRender,但 DataBinding 的约定是在 Load 中。

更新

我看到您正在向控件树动态添加控件。这充满了陷阱(但完全可行。)

a) 确保每次页面加载时都添加动态控件,而不仅仅是在回发时。回发/ View 状态保留状态(即数据),而不是对象。应该在OnInit中添加(OnLoad也可以,但是维护起来比较麻烦)。您当前仅添加回发,这就是第二次回发有效(而不是第一次)的原因

b) 仅初始化动态控件一次,就像任何其他控件一样 - 在 Load 中的 [!IsPostBack] 上。

-奥辛

关于asp.net - 仅在第二次单击时调用事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/840275/

相关文章:

javascript - jquery AJAX 中的 slideDown 传入数据

javascript - 事件监听器内的 'this' 是否始终引用同一个对象?

javascript - bool 函数来了解鼠标按钮的位置

javascript - 从除特定命名空间之外的所有命名空间取消绑定(bind)事件

c# - 从任务栏图标最小化恢复时,无边框窗口激活事件未触发

asp.net - 如何使用 J 查询使只读文本框在鼠标悬停时可编辑

c# - HttpResponse.End 与 HttpResponse.Close 与 HttpResponse.SuppressContent

c# - 在 html 电子邮件中发送 DataTable 的内容,从 DataTable 生成 HTML 的首选方法是什么?

不使用 Global.asax 启动 ASP.NET 应用程序

jquery - 未使用 jquery val() 方法调用 React 事件处理程序