【问题标题】:How do I trigger an update panel postback from a child page?如何从子页面触发更新面板回发?
【发布时间】:2009-10-22 16:48:36
【问题描述】:

我在网格视图中的每一行的单元格中都有一个更新面板。用户单击此更新面板中的链接按钮以显示(使用 window.open())弹出窗口。在该弹出窗口中采取了更新上述更新面板中包含的数据的操作。当弹出窗口关闭时,我只想为该更新面板触发更新。

最好的方法是什么?我正在研究捕获 window.close 事件并以某种方式传递一个值,该值指示从何处调用弹出窗口,然后在 javascript 中为该更新面板调用回发。如果它有所作为(至少它会 - 呃 - 在我的 javascript 代码中),我使用的是母版页并且只为 IE 编码。

找到了这个:http://forums.asp.net/p/1166328/1941797.aspx,它使用了 window.opener.document...同样,使用母版页会使事情复杂化。

【问题讨论】:

    标签: c# asp.net ajax gridview updatepanel


    【解决方案1】:

    您可以使用 javascript 函数 __doPostBack('eventTarget','eventArgument')。 在客户端可能看起来像这样。

    function showPopup()
    {
     var return = window.showModalDialog('someurl','','');
     if(return)
     {
      // do postback for update
      __doPostBack('<%= hiddenButton.ClientID %>','eventArgument');
     }
    }
    

    在服务器端,您应该使用带有 UpdateMode=Conditional 和隐藏按钮的更新面板,如 rick schott 所说。棘手的部分是要知道哪个单元格需要更新。如果您为 hiddenbutton 连接 OnClick,那么它将在调用 __doPostBack 时触发该事件。您可以从服务器端访问 Request.Form["__EVENTARGUMENT"] 以访问 __doPostBack 发送的值。例如,您可以使用此值来更新需要更新的单元格。

    【讨论】:

    • +1 因为这和我的想法一样,而且解释得很好。 @JBoyd 还阅读了此内容以获取有关 __doPostBack javascript 事件的更多信息aspalliance.com/895。使用这种方法我相信你可以触发更新现在仅限于特定的更新面板。在其关闭的方面,您可能希望使用关闭按钮而不是 window.close 事件并相应地链接 jscript。
    【解决方案2】:

    我是通过 Flash 应用程序完成的。如果你愿意的话,我的“hack”是用 CSS 隐藏一个真正的 ASP:Button。该按钮位于 UpdatePanel 内。我将 Button.ClientId 传递给外部资源(Flash、新窗口...等)。当外部资源(在我的例子中是 Flash)完成后,它会调用一个接受 ClientId 的 JavaScript 函数,并在按钮上调用 .Click()。

    JavaScript:

    function CallASPNETClick(id) {  
        var elmt = document.getElementById(id);   
        elmt.click();
    
    }
    

    标记:

    !--this is uses for capture an event from Flash with javascript, do not remove--->
    <asp:Button ID="hiddenButton" runat="server" Text="Button" style="visibility:hidden" OnClick="hiddenButton_Click" />
    

    【讨论】:

    • 这就是我一直在走的路。我遇到的麻烦是在使用隐藏按钮的 id 的代码中添加 OnClientClick 的代码(我使用的是母版页,所以 id 以“ctl00_MasterContentHolder_grdResources_ctl02_...”为前缀)当我在后面的代码中添加调用时不会被调用。我在 OnLoad 事件中像这样添加它: btnAdd.OnClientClick = "callback('" + sUpdateButtonID + "');";
    • 如果您将 JavaScript 硬编码为测试,会发生什么?如果您使用控件的 ClientId,它将为您解析其命名容器。
    • @JBoyd - 使用 SUpdateButton.ClientID 而不是仅使用 SUpdateButtonID。这将是 ASP 生成的 ID,其中包含添加到页面上每个控件的所有前缀内容。
    【解决方案3】:

    您可以使用调用页面上的隐藏字段来存储回调所需的任何值。弹出窗口可以使用 window.opener 来存储这些隐藏字段中的值。

    你可以扩展你的 window.open 函数来更新页面上的 javascript 变量并引用调用者:

    <asp:button onclientclick="buttonClicked(this)" />
    
    var lastButton;
    function buttonClicked(button) {
    lastButton = button;
    window.open(x);
    return false;
    }
    

    如果您将隐藏字段设置为 asp 控件,那么您将可以在更新面板的回发中访问它们。

    编辑:

    考虑一个模态弹出窗口,以消除人们在您希望他们使用弹出窗口时点击调用页面的问题。

    【讨论】:

      【解决方案4】:

      我选择的更简单(且有效)的解决方案是在 gridview 单元格的用户控件中使用 ModalPopupExtender 来实现这一点。用户控件包含只读结果网格和 ModalPopupExtender。弹出窗口允许您在父网格的单元格中编辑该网格的内容。单击“添加”按钮后,小网格会异步更新。

      一些关键项目最终让我找到了一个可行的解决方案......

      • 将 PopupControlId 属性中引用的面板内容包装在更新面板中
      • 在后面的代码中隐藏和显示模式弹出窗口
      • 一个简单的 good example 使用多个 ModalPopupExtenders 的网格视图

      【讨论】:

      【解决方案5】:

      这两种方式都适合我

      (1) 通过从 MasterPAge 引用 ChildPage

          ContentPlaceHolder_content.FindControl("dvwOrder").Controls.Clear();
          ((UpdatePanel)this.ContentPlaceHolder_content.FindControl("upOrders")).Update();
      

      此代码在母版页内,在我的按钮上单击我正在使用 contentplaceholder 来查找其中的控件引用。这里 dvwOrder 是我的 DataView,“upOrders”是我的 UpdatePanel。

      (2) 通过代表

      将此委托和事件处理程序放在母版页上的任何方法之外

          public delegate void RefreshButtonClickHandler(object
      

      发送者,EventArgs e); 公共事件 RefreshButtonClickHandler onRefreshButtonClick;

      在按钮单击事件的类中执行此操作

              if(null == onRefreshButtonClick)
              {
                  return;                
              }
      
              onRefreshButtonClick(sender, e);
      

      然后在子页面的 Page_Load 方法中将此事件与本地处理程序联系起来

              Child child = (child) this.Master;
              reports.onRefreshButtonClick += new
      

      孩子 .RefreshButtonClickHandler(reports_onRefreshButtonClick);

      Child 是我的代码隐藏文件的名称

      创建

          void child_onRefreshButtonClick(object sender, EventArgs e)
          {
      
          }
      

      你就完成了

      【讨论】:

        【解决方案6】:

        我放弃了在单独的窗口中执行此操作的努力,而是使用 AJAX ModalPopupExtender 开发了解决方案。 Matt Berseth 的 example 非常有帮助。

        为了更新父网格中更新面板中包含的子网格,我将单击按钮所在行的值存储在会话变量中,然后使用该值调用子网格的数据绑定方法用户已做出选择并点击保存。

        protected void btnShowSkillsetPopup_Click(object sender, EventArgs e)
        {
            // get the gridviewrow from the sender so we can get the datakey we need
            Button btnAddSkillsetsFromRow = sender as Button;
            GridViewRow row = (GridViewRow)btnAddSkillsetsFromRow.NamingContainer;
        
            Session["CapRes_ResourceRequestID"] = Convert.ToString(this.grdResources.DataKeys[row.RowIndex].Value);
            Session["CapRes_SkillsetUpdatePanel_Row"] = Convert.ToString(row.RowIndex);
            ModalPopupExtender.Show();
        }
        

        保存代码...

        int nUpdatePanelID = Convert.ToInt32(Session["CapRes_SkillsetUpdatePanel_Row"].ToString());
        UpdatePanel pnlSkillsetsMain = grdResources.Rows[nUpdatePanelID].FindControl("pnlSkillsetsMain") as UpdatePanel;
        GridView grdSkillsets = pnlSkillsetsMain.Controls[0].FindControl("CascadingSkillsets1").FindControl("grdSkillsets") as GridView;
        grdSkillsets.DataBind();
        
        ModalPopupExtender.Hide();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-28
          相关资源
          最近更新 更多