Ne pouvez pas obtenir ScriptManager.Registrerstartupscript dans WebControl imbriqué dans UpdatePanel pour fonctionner

j'ai ce que je crois être un problème assez simple, mais pour ma vie Je ne peux pas voir mon problème. Le problème est lié à ScriptManager.RegisterStartupScript, quelque chose que j'ai utilisé plusieurs fois auparavant.

Le scénario que j'ai est que j'ai un contrôle web personnalisé qui a été inséré dans une page. Le contrôle (et un ou deux autres) sont imbriqués dans un plan UpdatePanel. Ils sont insérés sur la page dans un espace réservé:

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

C'est le seul panneau de mise à jour sur la page.

la commande nécessite un javascript initial pour qu'elle fonctionne correctement. Le contrôle des appels:

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

et j'ai aussi essayé:

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

le problème est que le script s'exécute correctement lorsque la page est affichée pour la première fois, mais ne s'exécute pas après un postback partiel. J'ai essayé le code suivant:

  1. Appel RegisterStartupScript de CreateChildControls
  2. Appel Registrerstartupscript from OnLoad / OnPreRender
  3. utilisant différentes combinaisons de paramètres pour les deux premiers paramètres (dans l'exemple ci-dessus, le contrôle est Page et le Type est GetType (), mais j'ai essayé d'utiliser le contrôle lui-même, etc).
  4. j'ai essayé d'utiliser des ID persistants et nouveaux (non pas que je pense que cela devrait avoir un impact majeur de toute façon).
  5. j'ai utilisé quelques points d'arrêt et ainsi de vérifier que le Registre est appelé correctement.

la seule chose que je n'ai pas essayé est d'utiliser le canal de mise à jour lui-même comme le contrôle et le Type, car je ne pense pas que le contrôle devrait être conscient du panneau de mise à jour (et dans tous les cas il ne semble pas y avoir un bon moyen d'obtenir le panneau de mise à jour?).

Est-ce que quelqu'un peut voir ce que je fais de mal dans ce qui précède?

Merci :)


Eh bien, pour répondre à la question ci-dessus - il ne semble comme si le titulaire de place d'une façon ou d'une autre bousille le ScriptManager.Registrerstartupscript.

quand je sors le contrôle du conteneur et le code directement sur la page le script du registre fonctionne correctement (j'utilise aussi le contrôle lui-même comme paramètre).


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

Est-ce que quelqu'un peut jeter une lumière sur la raison pour laquelle un contrôle injecté sur un PlaceHolder empêcherait le ScriptManager d'enregistrer correctement le script? Je suppose que cela a quelque chose à voir avec le cycle de vie des commandes dynamiques, mais j'apprécierais (à ma connaissance) qu'il y ait un processus correct pour ce qui est de ce qui précède.

33
demandé sur Kev 2009-04-29 18:04:36

10 réponses

je pense que vous devriez en effet être à l'aide de la surcharge de contrôle du Régisterstartupscript.

j'ai essayé le code suivant dans un contrôle serveur:

[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);
    }
}

dans ma page j'ai:

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

où Placeholder1 est un placeholder dans un panneau de mise à jour. Le placeholder a un couple d'autres contrôles sur elle, y compris les boutons.

cela s'est comporté exactement comme vous vous y attendiez, j'ai reçu une alerte disant "bonjour" chaque fois que j'ai chargé la page ou fait mettre à jour le panneau de mise à jour.

l'autre chose que vous pouvez regarder est de vous connecter à certains événements du cycle de vie de la page qui sont lancés lors d'une demande de panel de mise à jour:

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

PageRequestManager endRequestHandler l'événement déclenche chaque fois qu'un panneau de mise à jour complète sa mise à jour - cela vous permettrait d'appeler une méthode pour configurer votre contrôle.

mes seules autres questions sont:

  • Quel Est votre script? en fait en train de faire?
  • vous pouvez probablement voir le script dans le HTML au bas de la page (juste avant la balise de fermeture )?
  • avez-vous essayé de mettre quelques appels "alert"("ici"); " dans votre script de démarrage pour voir si c'est correctement appelé?
  • Avez-vous essayé Firefox et Firebugg - est que la déclaration des erreurs de script?
15
répondu Zhaph - Ben Duguid 2009-04-29 22:03:07

j'ai eu un problème en utilisant ceci dans un contrôle d'utilisateur (dans une page cela a fonctionné très bien); le Button1 est à l'intérieur d'un updatepanel et scriptmanager sur le usercontrol.

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

maintenant il semble que vous devez faire attention avec les deux premiers arguments, ils doivent faire référence à votre page, pas à votre contrôle

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "alertscript", scriptstring, true);
34
répondu dc2009 2013-01-16 09:57:08

quand vous appelez ScriptManager.RegisterStartupScript, le paramètre "Control" doit être un contrôle qui se trouve dans un paquet UpdatePanel qui sera mis à jour. Vous avez besoin de le modifier:

ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), script, true);
10
répondu Keltex 2009-04-29 14:35:57

la solution est de mettre les scripts dans un fichier extérieur js (appelons 'yourDynamic.js') et réenregistrez de file à chaque fois que vous rafraîchissez le paanel de mise à jour.

j'utilise ceci dans l'événement updatepanel_prerender:

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

dans la page ou dans une autre include vous aurez besoin de ce 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;
                }
            }
        }
    }
}

Assez cool, ah...jejeje Cette partie de ce que j'ai posté il y a quelques temps ici.

Espérons que cette aide... :)

1
répondu Lucas 2009-04-29 20:42:48

J'ai eu un problème avec Page.ClientScript.RegisterStartUpScript-Je n'utilisais pas de panneau de mise à jour, mais le contrôle était caché. Cela signifiait que je devais insérer le script dans un littéral (ou pourrait utiliser un PlaceHolder) de sorte que lorsqu'il est rendu à partir du cache le script est inclus.

Une solution similaire pourrait fonctionner pour vous.

1
répondu s_hewitt 2009-04-29 20:55:11

N'utilisez pas GUID pour la touche

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

et si vous voulez faire cela , appelez quelque chose comme cette fonction

 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", "");
 }
1
répondu ahmad sarkar 2014-01-06 13:11:32

ce qui a fonctionné pour moi, c'est l'enregistrer sur la Page tout en spécifiant le type comme celui du UpdatePanel, comme ceci:

ScriptManager.RegisterClientScriptBlock(this.Page, typeof(UpdatePanel) Guid.NewGuid().ToString(), myScript, true);
0
répondu Alex 2009-12-22 11:46:33

parfois il ne démarre pas quand le script a une erreur de syntaxe, assurez-vous que le script et la syntaxe javascript sont corrects.

0
répondu Prema Tiwari 2011-01-20 07:45:41
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(),script,  true );

la valeur param" true " à la fin du ScriptManager.RegisterStartupScript ajoutera une balise JavaScript à l'intérieur de votre page:

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

si la valeur est "false", il n'injectera que le script avec la balise --script.

0
répondu ZoharAdar 2012-03-13 17:01:11

j'ai essayer beaucoup de choses et finalement trouvé que le dernier paramètre doit être faux et vous devez ajouter <SCRIPT> balise pour le java script :

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

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), key, script, **false**);
0
répondu Brian Mains 2014-04-15 14:48:58