Não é possível obter ScriptManager.RegisterStartupScript em WebControl aninhado em UpdatePanel ao trabalho

StackOverflow https://stackoverflow.com/questions/802506

Pergunta

Eu estou tendo o que eu acredito que deve ser um problema bastante simples, mas para a vida de mim eu não posso ver o meu problema. O problema está relacionado com ScriptManager.RegisterStartupScript, algo que eu tenho usado muitas vezes antes.

O cenário que tenho é que eu tenho um controle web personalizada que foi inserido em uma página. O controlo (e um ou dois outros) são encaixados dentro de um UpdatePanel. Eles são inseridos na página em um espaço reservado:

<asp:UpdatePanel ID="pnlAjax" runat="server">
  <ContentTemplate>
    <asp:PlaceHolder ID="placeholder" runat="server">
    </asp:PlaceHolder>
    ...

protected override void OnInit(EventArgs e){
  placeholder.Controls.Add(Factory.CreateControl());
  base.OnInit(e);
}

Este é o único painel de atualização na página.

O controle requer algum javascript inicial ser executado para que ele funcione corretamente. As chamadas de controle:

ScriptManager.RegisterStartupScript(this, GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

e eu também tentei:

ScriptManager.RegisterStartupScript(Page, Page.GetType(), 
                                    Guid.NewGuid().ToString(), script, true);

O problema é que o script é executado corretamente quando a página é exibida pela primeira vez, mas não executar novamente depois de um postback parcial. Eu tentei o seguinte:

  1. Chamando RegisterStartupScript de CreateChildControls
  2. Chamando RegisterStartupScript de OnLoad / OnPreRender
  3. Usando diferentes combinações de parâmetros para os dois primeiros parâmetros (no exemplo acima, o controle é da página eo tipo é GetType (), mas eu tentei usar o próprio controle, etc).
  4. Eu tentei usar ids persistentes e novas (não que eu acredito que este deve ter um grande impacto de qualquer forma).
  5. Eu usei alguns pontos de interrupção e assim por ter verificado que a linha Register está sendo chamado corretamente.

A única coisa que eu não tentei é usando o próprio UpdatePanel como o controle e Tipo, como eu não acredito que o controle deve estar ciente do painel de atualização (e em qualquer caso, não parece ser uma boa maneira de ficando o painel de atualização?).

Alguém pode ver o que eu poderia estar fazendo errado no exemplo acima?

Obrigado:)


Bem, para responder a consulta acima -. Que parece como se o espaço reservado de alguma forma, mexe-se o ScriptManager.RegisterStartupScript

Quando eu puxar o controle fora do espaço reservado e código-lo diretamente na página do Register script funciona correctamente (eu também estou usando o próprio controle como um parâmetro).

ScriptManager.RegisterStartupScript(this, GetType(), Guid.NewGuid().ToString(), script, true);

Alguém pode lançar alguma luz sobre por que um controle injecta-se um espaço reservado impediria a ScriptManager de registrar corretamente o script? Eu estou supondo que isso pode ter algo a ver com o ciclo de vida de controles dinâmicos, mas gostaria de receber (para o meu próprio conhecimento) se houver um processo correto para o acima.

Foi útil?

Solução

Eu acho que você deve realmente estar usando o Controle sobrecarga do RegisterStartupScript.

Eu tentei o seguinte código em um controle de servidor:

[ToolboxData("<{0}:AlertControl runat=server></{0}:AlertControl>")]
public class AlertControl : Control{
    protected override void OnInit(EventArgs e){
        base.OnInit(e);
        string script = "alert(\"Hello!\");";
        ScriptManager.RegisterStartupScript(this, GetType(), 
                      "ServerControlScript", script, true);
    }
}

Então, em minha página eu tenho:

protected override void OnInit(EventArgs e){
    base.OnInit(e);
    Placeholder1.Controls.Add(new AlertControl());
}

Onde PLACEHOLDER1 é um espaço reservado em um painel de atualização. O espaço reservado tem um casal de outros controles sobre nele, incluindo botões.

Esta comportou exatamente como seria de esperar, eu tenho um alerta dizendo "Olá" cada vez que eu carregar a página ou causado o painel de atualização para atualização.

A outra coisa que você poderia olhar é para ligar para alguns dos eventos de ciclo de vida página que são acionados durante um pedido de painel de atualização:

Sys.WebForms.PageRequestManager.getInstance()
   .add_endRequest(EndRequestHandler);

O evento PageRequestManager endRequestHandler dispara cada vez que um painel de atualização completa a sua atualização -. isso permitirá que você chamar um método para configurar o controle

As minhas únicas outras perguntas são:

  • O que é o seu script realmente fazendo?
  • Provavelmente, você pode ver o script no HTML na parte inferior da página (logo antes da tag de fechamento )?
  • Você já tentou colocar um "alerta de poucos (" aqui ");" chamadas em seu script de inicialização para ver se ele está sendo chamado corretamente?
  • Você já tentou Firefox e Firebug -? É que relatar quaisquer erros de script

Outras dicas

Eu tive um problema usando isso em um controle de usuário (em uma página deste funcionou bem); o Button1 está dentro de um updatepanel, eo scriptmanager está no usercontrol.

protected void Button1_Click(object sender, EventArgs e)  
{  
    string scriptstring = "alert('Welcome');";  
    ScriptManager.RegisterStartupScript(this, this.GetType(), "alertscript", scriptstring, true);  
}

Agora, parece que você tem que ter cuidado com os dois primeiros argumentos, eles precisam fazer referência a sua página, não seu controle

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true);

Quando você chama ScriptManager.RegisterStartupScript, o parâmetro "Control" deve ser um controle que está dentro de um UpdatePanel que será atualizado. Você precisa alterá-lo para:

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), script, true);

A solução é colocar os scripts no arquivo de um fora js (permite chamada 'yourDynamic.js') e volte a registar toda de arquivo que você atualizar o updatepanel.

Eu uso isso em caso updatepanel_prerender:

ScriptManager.RegisterClientScriptBlock(UpdatePanel1, UpdatePanel1.GetType(), "UpdatePanel1_PreRender", _
                   "<script type='text/javascript' id='UpdatePanel1_PreRender'>" & _
                   "include('yourDynamic.js');" & _
                   "removeDuplicatedScript('UpdatePanel1_PreRender');</script>" _
                   , False)

Na página ou em algum outro incluem você vai precisar deste javascript:

// Include a javascript file inside another one.
function include(filename)
{
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('src'))
        {
            if(scripts[x].getAttribute('src').indexOf(filename) != -1)
            {
                head.removeChild(scripts[x]);
                break;
            }
        }
    }

    script = document.createElement('script');
    script.src = filename;
    script.type = 'text/javascript';
    head.appendChild(script)
}

// Removes duplicated scripts.
function removeDuplicatedScript(id)
{
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].getAttribute('id'))
        {
            if(scripts[x].getAttribute('id').indexOf(id) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
    clearAjaxNetJunk();
}
// Evoids the update panel auto generated scripts to grow to inifity. X-(
function clearAjaxNetJunk()
{
    var knowJunk = 'Sys.Application.add_init(function() {';
    var count = 0;
    var head = document.getElementsByTagName('head')[0];

    var scripts = document.getElementsByTagName('script');
    var firstScript;
    for(var x=0;x<scripts.length;>    {
        if (scripts[x].textContent)
        {
            if(scripts[x].textContent.indexOf(knowJunk) != -1)
            {
                if (count == 0)
                {
                    firstScript = scripts[x];
                    count++;
                }
                else
                {
                    head.removeChild(firstScript);
                    firstScript = scripts[x];
                    count = 1;
                }
            }
        }
    }
}

Muito legal, ah ... hehehe Esta parte do que eu postei há algum tempo aqui .

Espero que isso ajuda ...:)

Eu tive um problema com Page.ClientScript.RegisterStartUpScript - eu não estava usando um painel de atualização, mas o controle foi armazenado em cache. Isso significava que eu tinha que inserir o script em um Literal (ou poderia usar um espaço reservado) para que quando processado a partir do cache do script está incluído.

A solução trabalho poderio semelhante para você.

Não use GUID para a chave

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) 
       Guid.NewGuid().ToString(), myScript, true);

e se você quiser fazer isso, chamar algo como esta função

 public static string GetGuidClear(string x)
 {
      return x.Replace("-", "").Replace("0", "").Replace("1", "")
              .Replace("2",  "").Replace("3", "").Replace("4", "")
              .Replace("5", "").Replace("6", "").Replace("7", "")
              .Replace("8", "").Replace("9", "");
 }

O que funcionou para mim, está registrando-o na enquanto especifica o tipo que o do UpdatePanel, assim:

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) Guid.NewGuid().ToString(), myScript, true);

Às vezes isso não acontecer fogo quando o script tem algum erro de sintaxe, verifique se o script e sintaxe javascript está correto.

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(),script,  true );

O "verdadeiro" valor param no final da ScriptManager.RegisterStartupScript irá adicionar uma tag JavaScript dentro de sua página:

<script language='javascript' defer='defer'>your script</script >

Se o valor será "false" que vai injetar somente o script witout a tag --script--.

Eu tento muitas coisas e, finalmente, descobriu que o último parâmetro deve ser falso e você deve adicionar tag <SCRIPT> para o java script:

string script = "< SCRIPT >alert('hello!');< /SCRIPT>";

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top