7
votes

Contrôles créés dynamiques à l'intérieur UpdatePanel?

Je veux créer un contrôle qui permettra à l'utilisateur de concevoir sa propre structure de site Web. J'ai imaginé que l'intérieur updatepanel est le (s) contrôle (code> textbox (pour nom de page) et bouton 'Ajouter ci-dessous'. On dirait que: xxx

Maintenant, lorsque l'utilisateur clique sur le bouton "Tags", il devrait apparaître un nouveau, entre "balises" et "badges", avec nom modifiable, afin que l'utilisateur puisse nommer Il "utilisateurs" par exemple. Il devrait être fait sans poteau complet (pour éviter les clignotements de page).

est maintenant mon problème: je ne peux pas charger ces contrôles (enfin non tous) dans Oninit depuis qu'ils n'existent pas, mais je dois Assister à l'événement de leur clic afin que je puisse attacher auditeur d'événements ce qui devrait être fait pendant la phase init. Comment puis-je atteindre la fonctionnalité décrite?

J'ai joué autour de cela pendant trop de temps et je suis confus. Je serais reconnaissant pour tous les conseils.


0 commentaires

3 Réponses :


-1
votes

Si vous souhaitez dynamique EventHandlers pour vos commandes, vous pouvez essayer ceci -

Considérant une commande de bouton, P>

void btnTest_Click(object sender, EventArgs e)
{
    //your code
}


0 commentaires

15
votes

Il s'agit d'une situation délicate car vous avez affaire à des contrôles dynamiques, vous devez les peupler à la page init afin de persister la vieilletate, ainsi que des événements pour les contrôles ajoutés à l'intérieur d'un panneau de mise à jour pendant les clics de bouton ne semble pas être enregistré avant le prochain. Post-plan-retour, donc le bouton normal Cliquez sur l'événement uniquement des incendies une fois que vous cliquez sur un contrôle nouvellement ajouté. Il peut y avoir une autre façon de travailler autour de cela que la façon dont je l'ai fait. Si quelqu'un sait que je voudrais savoir.

Ma solution consiste à conserver une liste de ce que vous avez ajouté de manière dynamique, et stockez-la dans une variable de session (car la visualisation n'est pas chargée pendant la page init). Ensuite, sur la page init, chargez les commandes que vous avez ajoutées précédemment. Ensuite, gérez l'événement de clic pendant la charge de la page avec un code personnalisé ou l'événement de clic normal. p>

J'ai créé une page d'exemple pour vous aider à tester cela. p>

Voici le code de la page ASPX (par défaut.aspx): p>

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

public partial class _Default : System.Web.UI.Page
{
    /// <summary>
    /// this is a list for storing the id's of dynamic controls
    /// I have to put this in the session because the viewstate is not
    /// loaded in the page init where we need to use it
    /// </summary>
    public List<string> DynamicControls
    {
        get
        {
            return (List<string>)Session["DynamicControls"];
        }
        set
        {
            Session["DynamicControls"] = value;
        }
    }

    protected void Page_Init(object sender, EventArgs e)
    {
        PlaceholderControls.Controls.Clear();

        //add one button to top that will cause a full postback to test persisting values--
        Button btnFullPostback = new Button();
        btnFullPostback.Text = "Cause Full Postback";
        btnFullPostback.ID = "btnFullPostback";
        PlaceholderControls.Controls.Add(btnFullPostback);

        PlaceholderControls.Controls.Add(new LiteralControl("<br />"));

        PostBackTrigger FullPostbackTrigger = new PostBackTrigger();
        FullPostbackTrigger.ControlID = btnFullPostback.ID;

        UpdatePanel1.Triggers.Add(FullPostbackTrigger);
        //-----------------------------------------------------------------------




        if (!IsPostBack)
        {
            //add the very first control           
            DynamicControls = new List<string>();

            //the DynamicControls list will persist because it is in the session
            //the viewstate is not loaded yet
            DynamicControls.Add(AddControls(NextControl));

        }
        else
        {
            //we have to reload all the previously loaded controls so they
            //will have been added to the page before the viewstate loads
            //so their values will be persisted
            for (int i = 0; i < DynamicControls.Count; i++)
            {
                AddControls(i);
            }
        }


    }

    protected void Page_Load(object sender, EventArgs e)
    {

        if (!IsPostBack)
        {
            //we have to increment the initial
            //control count here here be cause we cannot persit data in the viewstate during 
            //page init

            NextControl++;

        }
        else
        {
            HandleAddNextClick();           

        }

    }

    /// <summary>
    /// this function looks to see if the control which caused the postback was one of our 
    /// dynamically added buttons, we have to do this because the update panel seems to interefere
    /// with the event handler registration.
    /// </summary>
    private void HandleAddNextClick()
    {
        //did any of our dynamic controls cause the postback if so then handle the event
        if (Request.Form.AllKeys.Any(key => DynamicControls.Contains(key)))
        {
            DynamicControls.Add(AddControls(NextControl));
            NextControl++;
        }
    }



    protected void btnAddNext_Command(object sender, CommandEventArgs e)
    {
        //this is intentionally left blank we are handling the click in the page load
        //because the event for controls added dynamically in the click does
        //not get registered until after a postback, so we have to handle it 
        //manually.  I think this has something to do with the update panel, as it works 
        //when not using an update panel, there may be some other workaround I am not aware of

    }

    /// <summary>
    /// variable for holding the number of the next control to be added
    /// </summary>
    public int NextControl
    {
        get
        {
            return  ViewState["NextControl"] == null ? 0 : (int)ViewState["NextControl"];
        }
        set
        {
            ViewState["NextControl"] = value;
        }
    }


    /// <summary>
    /// this function dynamically adds a text box, and a button to the placeholder
    /// it returns the UniqueID of the button, which is later used to find out if the button
    /// triggered a postback
    /// </summary>
    /// <param name="ControlNumber"></param>
    /// <returns></returns>
    private string AddControls(int ControlNumber)
    {
        //add textbox
        TextBox txtValue = new TextBox();
        txtValue.ID = "txtValue" + ControlNumber;
        PlaceholderControls.Controls.Add(txtValue);

        //add button
        Button btnAddNext = new Button();
        btnAddNext.Text = "Add Control " + ControlNumber;
        btnAddNext.ID = "btnAddNext" + ControlNumber;
        int NextControl = ControlNumber + 1;
        btnAddNext.CommandArgument = NextControl.ToString();

        btnAddNext.Command += new CommandEventHandler(btnAddNext_Command);
        PlaceholderControls.Controls.Add(btnAddNext);

        //add a line break
        PlaceholderControls.Controls.Add(new LiteralControl("<br />"));

        return btnAddNext.UniqueID;

    }    
}


5 commentaires

Je vérifierai certainement votre solution après le travail et vous donnerai plus de commentaires. Merci beaucoup d'échantillon même si je ne l'ai pas demandé!


Fonctionne comme un charme :) J'ai oublié / je ne connaissais pas peu de fonctionnalités que vous avez utilisées pour que la solution à minière était incomplète. Merci beaucoup! Tu m'as beaucoup aidé :)


Heureux que je puisse aider, j'aimerais qu'il y ait un moyen de le faire sans utiliser la session, mais je ne connais aucun autre moyen facile de stocker et de récupérer des informations avant la charge de visualisation. Vous pouvez probablement utiliser des champs ou des biscuits cachés, mais ceux-ci semblent avoir même porté des idées. Peut-être qu'il y a un moyen de charger manuellement la visualisation et d'l'utiliser dans la page init.


Ce n'est pas vrai. Chargement d'une commande de manière dynamique dans Onload fonctionnera bien - Tant que l'arborescence de contrôle est la même! - Parce que les événements se "rattraperont". Je restaure les commandes dynamiques de la vision du vietate tout le temps. Je ne stocke pas stocker le contrôle, l'esprit, mais plutôt les "informations nécessaires pour savoir comment reconstruire l'arborescence de contrôle". L'important est de reconstruire le même arbre. Pour vous assurer que l'arborescence de contrôle est la même en utilisant un Contrôle de l'espace réservé (qui est chargé à init, peut-être dans le balisage) est une technique utile: la vue de la vue lit comme arbre .


(Quand je dis que je dis que le contrôle de l'espace réservé est chargé à init, je ne veux pas dire que les enfants dynamiques sont nécessairement chargés à init: créer / ajouter les enfants enfants peuvent être différés à Chargez lorsque la page de visée de la page / de l'espace réservé est accessible. Lorsque les enfants sont créés / ajoutés, ils passeront par le processus d'init / i> init / i> init / i>. Le spectacle supplémentaire ne jette pas la principale init / charge en raison de la structure semblable à l'arbre dans laquelle il est stocké!)



0
votes

de cette façon de travailler pour moi xxx

dans le bouton appelle xxx

Avant d'appeler la méthode effacer la commande sinon elle se chargera deux fois.


0 commentaires