ASP.net : Dynamische Controls

  1. Wat zijn Dynamische Controls ?
  2. Dynamische Controls maken
  3. Events bij Dynamische Controls
  4. User Controls dynamisch laden
  5. Oefeningen

Wat zijn Dynamische Controls ?

Dynamische controls zijn controls die je runtime aanmaakt. In plaats van gebruik te maken van de ToolBox en controls op een Web Form neer te plaatsen - of in de HTMLcode de tag voor een control in te geven - maak je de control runtime aan.

Als je controls runtime aanmaakt voeg ze toe aan de Controls-collectie van de pagina of van een andere Control.

Daar we graag controle hebben op de plaatsing van de runtime controls plaatsen we een PlaceHolder Control op plaats waar we dynamische gemaakte controls willen plaatsen. Deze Control houdt gewoon plaats voor andere controls.

Dynamische Controls maken: OnInit

We plaatsen een PlaceHolder en een Button op de pagina, zodat we kunnen experimenteren met PostBack.

We maken nu runtime een TextBox aan en voegen die toe via de PlaceHolder.

Wanneer je drukt op de knop verdwijnt de TextBox!

<pre>
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace LaadControls
{
	/// <summary>
	/// Summary description for Inleiding.
	/// </summary>
	public class Inleiding : System.Web.UI.Page
	{
        protected System.Web.UI.WebControls.PlaceHolder PH;
        protected System.Web.UI.WebControls.Button btnVerzenden;
    
		private void Page_Load(object sender, System.EventArgs e)
		{
            if(!IsPostBack)
            {
                TextBox txt = new TextBox();
                PH.Controls.Add(txt);
                txt.Text = "Starttekst";
            }
            
		}

		...
}


Gezien elke webaanvraag onafhankelijk wordt gezien door de server wordt bij een PostBack de TextBox niet meer aangemaakt. Run-time Controls moet je bijgevolg bij elke pagina-aanvraag opnieuw aanmaken.

We doen een aanpassing in de code en voegen nog een Label toe met de ToolBox:

public class Inleiding : System.Web.UI.Page
	{
        protected System.Web.UI.WebControls.PlaceHolder PH;
        protected System.Web.UI.WebControls.Label lblTest;
        protected System.Web.UI.WebControls.Button btnVerzenden;
    
		private void Page_Load(object sender, System.EventArgs e)
		{  
           
            TextBox txt = new TextBox();
            PH.Controls.Add(txt);
            txt.Text = "Starttekst";
            
            lblTest.Text = txt.Text;
		}
}

Verander de tekst in de TextBox en druk op de knop. Je merkt dat de tekst in de TextBox aangepast blijft, door de ViewState. De ViewState wordt echter weggeschreven na de Page_Load: de tekst in de TextBox wordt dus eerst Starttekst door de Page_Load en wordt achteraf door de ViewState aangepast tot de ingebrachte tekst. Aagezien de Page_Load routine nu reeds is uitgevoerd blijft de tekst van het Label Starttekst.

Meer hierover bij 4GuysFromRolla.

We doen volgende aanpassing:

private void Page_Load(object sender, System.EventArgs e)
		{  
            lblTest.Text = ((TextBox)FindControl("T1")).Text;
		}

		override protected void OnInit(EventArgs e)
		{
            ...
			
			TextBox txt = new TextBox();
            PH.Controls.Add(txt);
            txt.Text = "Starttekst";
            txt.ID = "T1";
            
            
            
            ...
		}
We zetten het maken van de control in de routine Page_OnInit: deze routine wordt uitgevoerd voor de ViewState wordt geladen. We schrijven dus initieel de tekst StartTekst in de TextBox. Na OnInit wordt de ViewState geladen. De tekst in de TextBox verandert hierdoor in de waarde die de gebruiker heeft ingegeven. Een verwijzing naar de TextBox in Page_Load zorgt er nu voor dat de reële waarde uit de ViewState wordt ingelezen. Hierdoor kunnen we ervoor zorgen dat de juiste waarde zowel in de TextBox als in het Label verschijnen.

Hier gebruiken we de methode FindControl om een referentie op te bouwen naar de TextBox. Je kan natuurlijk ook werken met een instantievariabele:

		protected TextBox txt;
    
		private void Page_Load(object sender, System.EventArgs e)
		{  
            lblTest.Text = txt.Text;
		}

Event Handlers bij dynamische controls

Een probleem met dynamische controls is dat wanneer je een editor als Visual Studio gebruikt, je misschien gewoon bent om event hanler-methoden te installeren door eenvoudigweg de eigenschappen van een control op te vragen in design-modus.

Met dynamisch gecreëerde controls kan dit natuurlijk niet. Je zal de event-hanlers dus zelf moeten koppelen.

In deze toepassing laten we 5 CheckBox-controls verschijnen en zorgen we voor een gepaste melding wanneer deze controls gemanipuleerd worden.

We voorzien een variable boxen op klasseniveau, deze variabele bevat een array van CheckBox-controls.

In de methode OnInit doen we een aanroep van de metode LaadUI, hierin bouwen onze dynamische controls op. We voorzien elke CheckBox van een event-handler voor het event CheckedChanged.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace LaadControls
{
	/// <summary>
	/// Summary description for DynamicEvent.
	/// </summary>
	public class DynamicEvent : System.Web.UI.Page
	{
        protected System.Web.UI.WebControls.PlaceHolder PH;
        protected System.Web.UI.WebControls.Label lblVerander;
        protected CheckBox[] boxen;

		private void Page_Load(object sender, System.EventArgs e)
		{
			// Put user code to initialize the page here
		}

        private void LaadUI()
        {
            int aantal = 5;
            boxen = new CheckBox[aantal];
            for(int i = 0; i < aantal; i++)
            {
                boxen[i] = new CheckBox();
                boxen[i].ID = "Box" +i.ToString();
                boxen[i].AutoPostBack = true;
                boxen[i].Text = "Kruis me aan";
                boxen[i].CheckedChanged += new EventHandler(this.CB_CheckedChanged);
                PH.Controls.Add(boxen[i]);
            }
        }

        private void CB_CheckedChanged(object sender, System.EventArgs e)
        {
            CheckBox cb = (CheckBox)sender;
            lblVerander.Text += "Verandering in: " +cb.ID +"<br>"
                    +"Waarde is nu: " +cb.Checked +"<p>";
        }

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
			
			LaadUI();
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
            this.Load += new System.EventHandler(this.Page_Load);

        }
		#endregion
	}
}

User Controls dynamisch laden

In het vorige hoofdstuk leerden we User Controls aanmaken. Deze controls kunnen we ook dynamisch laden.

Werk je met een User Control in een ascx-bestand, dan gebruik je de methode LoadControl.
Voeg de kalendercontrol toe in het huidige project via de Solution Explorer: add Existing Item. Selecteer het ascx-bestand, VS.net zal automatisch het ascx.cs bestand meekopiëren.
Vanzelfsprekend kan je het pad naar de ascx-file ook relatief opbouwen naar de originele locatie.

Werk je met een gecompileerde User Control in een dll-bestand, dan hoef je enkel een referentie te leggen naar de dll en kan je de control gebruiken als een gewone control. Vergeet de using clausule bovenaan de pagina niet als je de naam van de namespace niet telkens wenst in te tikken.

Hier maken we ook kennis met een nieuwe Web Control: Literal. Met deze control kan je een letterlijk stukje tekst invoegen. Hier gebruiken we een Literal om een P-tag tussen onze controls in te voegen.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using MaakCustomBox;

namespace LaadControls
{
	/// <summary>
	/// Summary description for dynUserControl.
	/// </summary>
	public class dynUserControl : System.Web.UI.Page
	{
        protected System.Web.UI.WebControls.PlaceHolder ph;
    
		private void Page_Load(object sender, System.EventArgs e)
		{
			// Put user code to initialize the page here
		}

        private void LaadUI()
        {
            Control kal = LoadControl("Kalender.ascx");
            ph.Controls.Add(kal);
            
            Literal l = new Literal();
            ph.Controls.Add(l);
            l.Text = "<p>";

            CustomBox cb = new CustomBox();
            ph.Controls.Add(cb);
            cb.ID = "CB";
            cb.Inhoud = "Een dynamische Custom Box";
            cb.Titel = "CB";
            cb.Width = new Unit("200px");
        }

		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);

            LaadUI();
		}
		
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{    
            this.Load += new System.EventHandler(this.Page_Load);

        }
		#endregion
	}
}


Oefeningen

Oefeningen

Meer tutorials:
leer ook: html | xhtml | css | asp | asp.net | c# | ado.net | linq | ajax | java | javascript
Valid HTML 4.01! Valid CSS! © - Cursusweb