2012-04-06 22 views
0

カスタムサーバーコントロールのOnPreRenderでは、ページが部分的なポストバック(add_pageLoaded(function(){alert( 'Hi')}))の後に読み込まれるたびに、 。私はこれを一度呼びたいだけですが、部分的なポストバックがあるのと同じくらい何回も呼び出されます。たとえば、以下のコードでは、ページを開いて「Click me」をクリックすると1つのアラートが表示され、もう一度クリックすると、2つのアラート、3つ以上のアラートなどが表示されます。 ScriptManager.RegisterClientScriptBlockは、scriptKeyパラメータを使用して、スクリプトがすでに登録されているかどうかを確認していた場合は、再度登録しないでください。 私のカスタムコントロールはポストバック中にページに挿入されるため、このスクリプトを!IsPostBackに登録することはできません。!IsPostBackを使用すると、スクリプトは含まれません。ここでScriptManager.RegisterClientScriptBlockを2回登録する

は、この問題の簡単な例です:

ASPX:背後

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"           Inherits="RegisterClientScriptExperimentation._Default" %> 
<%@ Register Assembly="RegisterClientScriptExperimentation"   Namespace="RegisterClientScriptExperimentation" TagPrefix="cc" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" > 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <div>  
     <asp:ScriptManager ID="ScriptManager1" runat="server"/>  
     <asp:UpdatePanel runat="server"> 
      <ContentTemplate> 
       <asp:Panel ID="panel" runat="server"/>      
      </ContentTemplate> 
     </asp:UpdatePanel>   
    </div> 
    </form> 
</body> 
</html> 

コード:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Text; 

namespace RegisterClientScriptExperimentation 
{ 
    public partial class _Default : System.Web.UI.Page 
    { 
     protected override void OnInit(EventArgs e) 
     { 
      base.OnInit(e); 
      panel.Controls.Add(new CustomControl()); 
     } 
    } 

    public class CustomControl : CompositeControl 
    { 
     private Button button; 
     public CustomControl() 
     { 
      button = new Button(); 
      button.Text = "Click me"; 
     } 
     protected override void CreateChildControls() 
     { 
      Controls.Clear(); 
      Controls.Add(button); 
     } 
     protected override void OnPreRender(EventArgs e) 
     { 
      base.OnPreRender(e); 

      StringBuilder _text = new StringBuilder(); 
      _text.Append("var prm = Sys.WebForms.PageRequestManager.getInstance();"); 
      _text.Append("prm.add_pageLoaded(function() { alert('Page Loaded'); });"); 

      if (null != System.Web.UI.ScriptManager.GetCurrent(Page) && System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack) 
       System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "customControlScript", _text.ToString(), true); 
      else 
       Page.ClientScript.RegisterStartupScript(this.GetType(), "customControlScript", _text.ToString(), true); 
     } 
    } 
} 

答えて

0

私はこれに対する解決策を見つけました。

あなたのページイベントでは、実行する必要のあるものを実行した後に、あなたがフックしたイベントからその機能を削除する必要があります。例えば

:!の

var prm = Sys.WebForms.PageRequestManager.getInstance(); 
prm.add_pageLoaded(DoSomething); 

function DoSomething() { 
    alert('Hello'); 
    Sys.WebForms.PageRequestManager.getInstance().remove_pageLoaded(DoSomething); 
} 
0
 if(!Page.ClientScript.IsClientScriptBlockRegistered("customControlScript") && !Page.IsPostBack) 
     { 

     if (null != System.Web.UI.ScriptManager.GetCurrent(Page) && System.Web.UI.ScriptManager.GetCurrent(Page).IsInAsyncPostBack)    
      System.Web.UI.ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "customControlScript", _text.ToString(), true);    
     else 
      Page.ClientScript.RegisterStartupScript(this.GetType(), "customControlScript", _text.ToString(), true); 
     } 
+0

私はコントロールがポストバックに追加されますので、それゆえ、私はPage.IsPostBackを確認することができない、一部のポストバックのページには、このコントロールを挿入します。私はIsPostBackなしで試してみて、それは常に登録されていないとして返されるようです。私はあなたがScriptManagerを使用して登録されたスクリプトをチェックするPage.ClientScriptメソッドを使用することはできないと思う – BlueChameleon

関連する問題