Programmeren in ASP.NET/HTML-controls
Wat is een server-control?
[bewerken]Vooraleer je begint met HTML-server-controls, moet je een basisconcept hebben van wat een server-control is. Server-controls zijn speciale tags die door de webserver op ongeveer dezelfde manier verwerkt worden als HTML-tags door je browser. Je kunt server-control-tags herkennen doordat ze een runat="server" attribuut hebben. Dit helpt de server om ze te onderscheiden van standaard HTML-tags of van andere soorten tekst waar de server niets mee te maken heeft.
Eigenaardig genoeg bestaat er geen runat="client" attribuut. Als je een pagina opvraagt met het "runat"-attribuut ingesteld als client (of iets anders) krijg je een "parser error" die je zegt dat "The Runat attribute must have the value Server." Wanneer de server een server-control tegenkomt zal hij in het geheugen een object aanmaken dat die server-control voorstelt. Dit object kan property's en methodes hebben, en het kan zelfs server-events oproepen tijdens de verwerking van de ASP.NET pagina. Als de verwerking gedaan is, zal de control zijn output in de vorm van HTML opmaken en dit wordt dan naar de browser gestuurd als onderdeel van de resulterende pagina.
Er zijn vijf soorten server-controls:
- HTML-controls
- web-controls
- user-controls
- custom controls
- web parts
Dit hoofdstuk behandelt de eerste soort server-controls meer in detail: HTML-controls. Het volgende hoofdstuk gaat over web-controls.
Wat zijn HTML-controls?
[bewerken]HTML-server-controls zijn eenvoudig een verzameling server-controls die erg lijken op hun overeenkomstige HTML-tags. In feite moet je om een HTML-server-control op een pagina te declareren alleen een bestaande HTML-tag nemen en het eerder genoemde runat="server"-attribuut toevoegen. Als er een HTML-server-control is die correspondeert met de HTML-tag die je hebt "gecontroliseerd", wordt de HTML-tag het overeenkomstige type van server-control. Anders zal het eenvoudig een HTML-control worden van het standaardtype HtmlGenericControl.
HTML-controls
[bewerken]De eerste soort van server-control, de HTML-control, lijkt erg veel op een standaard HTML-tag. Het enige verschil is dat zij een speciaal runat="server" attribuut bevat. Hier is een simpel voorbeeld met alleen HTML:
imagevoorbeeld.htm
<html>
<head>
<title>ASP.NET image</title>
</head>
<body>
<img id="imgVoorbeeld" src="images/voorbeeld.gif" />
</body>
</html>
In een eerste stap maken we er een aspx-pagina van:
imagevoorbeeld1.aspx
<%@ Page Language="VB" %>
<html>
<head>
<title>ASP.NET image</title>
</head>
<body>
<img id="imgVoorbeeld" src="images/voorbeeld.gif" runat="server" />
</body>
</html>
Een gewone image zou op deze manier geschreven worden:
<img id="imgVoorbeeld" src="images/voorbeeld.gif">
Om er een HTML-control van te maken, voeg je runat="server" toe.
<img id="imgVoorbeeld" src="images/voorbeeld.gif" runat="server" />
Als je Visual Studio gebruikt, kan je gewoon rechtsklikken op het HTML-element in Design View en "Run as Server Control" selecteren in het snelmenu.
De afbeelding heeft het runat="server"-attribuut gekregen, waardoor ze in een HTML-control veranderd is. De tag kreeg ook een id-attribuut zodat je ernaar kan refereren in je code. Zo geef je dus een naam aan een HTML-control.
De eerste regel is het zogenaamde "Page-directief", waarin de taal van de pagina ingesteld wordt. Voorlopig is er nog geen code aanwezig.
De HTML-code van het resultaat is de volgende:
<html>
<head>
<title>ASP.NET image</title>
</head>
<body>
<img src="/images/voorbeeld.gif" />
</body>
</html>
Het runat="server"-attribuut is in het resultaat verdwenen, net zoals de eerste regel.
De coderegel om de afbeelding te veranderen is nu heel gemakkelijk: imgVoorbeeld.src = "images/bloem.gif"
Je gebruikt dus de ID van de control om de eigenschappen ervan in te stellen.
Merk op hoe de property van de control (.src) dezelfde naam heeft als het attribuut van de overeenkomstige HTML <img>-tag (src).
imagevoorbeeld2.aspx
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)
imgVoorbeeld.src = "images/bloem.gif"
End Sub
</script>
<html>
<head>
<title>ASP.NET image</title>
</head>
<body>
<img id="imgVoorbeeld" src="images/voorbeeld.gif" runat="server" />
</body>
</html>
Opmerkingen
- de code staat tussen <script>-tags, die ook weer het attribuut runat="server" hebben.
- in deze pagina staat de code binnen een subroutine Page_Load. Deze routine is in feite een event dat wordt uitgevoerd telkens vóór de pagina in HTML omgezet wordt.
- Page_Load heeft een welbepaalde signatuur: er zijn 2 vaste parameters nodig. Dit is de juiste schrijfwijze:
Sub Page_Load(ByVal Sender As Object, ByVal E As EventArgs)
In het geval van Page_Load worden deze parameters (Sender en E) zelden gebruikt.
- Je kan Page_Load ook snel toevoegen in Visual Studio door te dubbelklikken op het formulier.
- alle attributen van de HTML-control (hier de afbeelding) zijn toegankelijk in de code onder de vorm controlID.naamAttribuut. In het voorbeeld wordt het src-attribuut van de afbeelding gewijzigd door aan imgVoorbeeld.src een andere waarde te geven.
- de afbeelding wordt eerst ingesteld ("design time") op "images/voorbeeld.gif", maar daarna wordt dit in Page_Load ("run time") veranderd in "images/bloem.gif". Het is deze laatste afbeelding die de gebruiker te zien krijgt.
Nog een stapje verder: nu voeg je een knop toe, en deze knop krijgt een onServerClick-attribuut (hier met de waarde actieKlik). Vervang Page_Load door actieKlik.
imagevoorbeeld3.aspx
<%@ Page Language="VB" %>
<script runat="server">
Sub actieKlik(Sender As Object, E As EventArgs)
imgVoorbeeld.src = "images/bloem.gif"
End Sub
</script>
<html>
<head>
<title>ASP.NET image</title>
</head>
<body>
<form runat="server">
<img id="imgVoorbeeld" src="images/voorbeeld.gif" runat="server" />
<input id="btnActie" type="button" value="Actie" runat="server"
onServerClick="actieKlik" />
</form>
</body>
</html>
Nu kan je de afbeelding veranderen door op de knop te klikken.
Opmerkingen
- Om dit te laten werken, moet je ook een <form>-tag toevoegen. Deze moet ook het runat="server" attribuut hebben.
- De subroutine actieKlik is nu de event-handler voor wanneer er op de knop geklikt wordt.
Deze event-handler heeft dezelfde signatuur als Page_load:
Sub actieKlik(Sender As Object, E As EventArgs)
De eerste parameter Sender verwijst naar het object dat het event veroorzaakt, in dit geval btnActie. De tweede parameter E bevat bijkomende informatie over het event. Later zullen we deze parameters soms gebruiken.
Zelfs een simpele <p>-tag kan een HTML-control worden, zoals in het voorbeeld hieronder:
helloworld3.aspx
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(Sender As Object, E As EventArgs)
HelloWorld.InnerText = "Hello World! " & Now()
End Sub
</script>
<html>
<head>
<title>ASP.NET Hello World</title>
</head>
<body>
<p id="HelloWorld" runat="server"></p>
</body>
</html>
Nota: de <p>-tag heeft geen overeenkomstige HTML-control en wordt daarom verwerkt als een control van het type HtmlGenericControl. Deze heeft een eigenschap InnerText, die je kan gebruiken om de inhoud van de tag te veranderen.
Hoe werkt het?
[bewerken]Bij het opvragen van deze pagina merkt de server dat het een aspx-pagina is, en zal de ASP.NET-engine in werking treden. De eerste keer wordt de pagina gecompileerd. Dit betekent dat de code vertaald wordt in machinecode, en deze wordt opgeslagen in een uitvoerbaar bestand. ASP.NET gebruikt hiervoor de extensie .dll (van Dynamic Link Library). Je vindt deze DLL terug in de folder "c:\Windows\Microsoft.NET\Framework\vx.x.xxxx\Temporary ASP.NET Files" (vervang indien nodig c:\Windows door de juiste folder waar Windows geïnstalleerd werd, en vx.x.xxxx door de versie van het .NET framework).
Daarna wordt bij het opvragen van de pagina altijd deze DLL gebruikt. Alle volgende aanvragen zullen dus sneller verwerkt worden, omdat het compileren niet meer moet gebeuren. Als je het originele bestand wijzigt, dan wordt de DLL wel opnieuw gecompileerd. Dit gebeurt volledig automatisch bij de eerste aanvraag. ASP.NET vergelijkt hiervoor de datum van het aspx-bestand en van de DLL.
Deze DLL bevat nu de juiste code om een HTML-pagina aan te maken, en deze pagina wordt uiteindelijk naar de gebruiker gestuurd.
Het nut van HTML-controls
[bewerken]HTML-server-controls weerspiegelen dus hun overeenkomstige HTML-tags en voeren eenvoudig de HTML-tags uit tijdens het gebruik. Waarom heb je die controls dan nodig? De controls vereenvoudigen sterk het werken met de property's en attributen van de HTML-tags. Ze laten je ook toe de logica die de tags beïnvloedt weg te verplaatsen van de tags zelf. Zo kan je nettere code schrijven.
0to9.aspx
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load(Sender as Object, E as EventArgs)
Randomize()
Dim int0to9 As Integer = Math.Floor(Rnd()*10)
imgVoorbeeld.Src = "images/digit_" & int0to9 & ".gif" ' stel afbeelding in
imgVoorbeeld.Alt = int0to9
End Sub
</script>
<html>
<head>
<title>ASP.NET Number Images</title>
</head>
<body>
<img id="imgVoorbeeld" runat="server" />
</body>
</html>
Als je deze pagina opvraagt krijg je bijvoorbeeld dit resultaat:
<html>
<head>
<title>ASP.NET Number Images</title>
</head>
<body>
<img src="images/digit_4.gif" id="imgVoorbeeld" alt="4" />
</body>
</html>
Merk op dat er geen enkele variabele of geen enkele code buiten het ene nette script blok staat. Server-controls maken deze flexibiliteit mogelijk. Je kan zelfs alle code in een apart bestand (bv. 0to9.aspx.vb) zetten. Dit doe je door bij de creatie van een nieuwe pagina de optie "Place code in separate file" aan te vinken. In de pagina krijg je dan bij het Page-directief de volgende attributen:
- Versie 1.1: Codebehind="0to9.aspx.vb" Inherits="0to9".
- Versie 2.0: CodeFile="0to9.aspx.vb" Inherits="0to9"
Hoe gebruik je ze?
[bewerken]Het codevoorbeeld hierboven heeft je een idee gegeven hoe HTML-controls gebruikt worden. Voor alle duidelijkheid is hier een lijst die illustreert hoe je kan spelen met sommige van de property's en methodes van een HtmlGenericControl.
Hier is een lijst met alle HTML-controls die beschikbaar zijn in ASP.NET. Al deze controls schrijven standaard HTML naar het webformulier:
Control | Beschrijving | Belangrijkste eigenschappen | Resultaat in HTML |
HtmlGenericControl | Kan gebruikt worden voor tags waar geen andere HTML-control voor bestaat, zoals <body>, <span>, <p> of <div> | InnerText InnerHTML | |
HtmlAnchor | Link of anchor | href, Target | <a href="www.com"> </a> |
HtmlForm | Formulier | Method, Target | <form runat="server"></form> |
HtmlInputText | Invoerveld | Value, Size | <input type="text" runat="server" /> |
HtmlInputText (Password) | Invoerveld voor wachtwoorden | Value | <input type="password" runat="server" /> |
HtmlTextArea | Invoerveld dat meerdere regels toelaat. | Value, Size, Rows | <input type="textarea" runat="server"></textarea> |
HtmlInputHidden | Verborgen veld | Value | <input type="hidden" runat="server" /> |
HtmlButton | Knop | Value | <input type="button" runat="server" /> |
HtmlInputReset | Reset knop | Value | <input type="reset" runat="server" /> |
HtmlInputSubmit | Submit knop | Value | <input type="submit" runat="server" /> |
HtmlInputFile | Toont een tekstveld en een Browse knop op het formulier, zodat de gebruiker een bestand van zijn computer kan selecteren. | Value | <input type="file" runat="server" /> |
HtmlInputCheckBox | aankruisvakje | Checked | <input type="checkbox" runat="server" /> |
HtmlInputRadioButton | radioknop | Checked, Value | <input type="radio" runat="server" /> |
HtmlImage | Toont een afbeelding | Src, Alt | <img src="bloem.gif" runat="server" /> |
HtmlInputImage | Zelfde als HtmlImage, maar werkt als een knop | Src | <input type="image" src="bloem.gif" runat="server" /> |
HtmlTable | laat toe om informatie in tabelvorm te presenteren. | Rows | {| runat="server" |} |
HtmlTableRow | Rij in een HtmlTable | Cells | <tr> </tr> |
HtmlTableCell | Cel in een HtmlTableRow | InnerHTML | <td> </td> |
HtmlSelect | Toont een lijst met items | Value, SelectedIndex, Size, Items, Multiple | <select size="2" runat="server"></select> |
HtmlHead (2.0) | Geeft toegang tot de <head>-tag in een pagina | ||
HtmlLink (2.0) | Geeft toegang tot de <link>-tag in een pagina | ||
HtmlTitle (2.0) | Geeft toegang tot de <title>-tag in een pagina |
Aan de meeste HTML-controls kan je client-side-events koppelen, zoals onClick, onFocus en onMouseOver. Deze events worden dan gekoppeld aan standaard JavaScript-code, die op de client uitgevoerd wordt.
Daarnaast zijn er ook enkele events die op de server kunnen uitgevoerd worden:
Server-Side Event | Beschrijving | Beschikbaar bij |
OnServerChange | Gebeurt op de server als de waarde van de control veranderd is ten opzichte van de vorige post | HtmlInputText, HtmlTextArea, HtmlSelect, HtmlInputCheckbox, HtmlInputRadiobutton, HtmlInputHidden |
OnServerClick | Gebeurt op de server als er op de control geklikt wordt. | HtmlButton, HtmlAnchor, HtmlInputButton, HtmlImage |
In dit voorbeeld worden drie knoppen getoond met zowel onClick- als onServerClick-events:
serverclicktest.aspx
<%@ Page Language="VB" EnableViewState="False" %>
<script runat="server">
Sub Page_Load(Sender As Object, E As EventArgs)
button1.value="Button1 - gewijzigd"
button2.value="Button2 - gewijzigd"
'button3.value="Button3 - gewijzigd" ' Werkt niet: geen server control
End Sub
Sub SButton_Click(sender As Object, e As EventArgs)
label.InnerHtml = "geklikt via server"
End Sub
</script>
<html>
<head>
<script language="JavaScript">
function Button_Click(i) {
document.form2.tekstvak.value="geklikt op knop "+i;
}
</script>
</head>
<body>
<form runat="server">
<!-- server side button: onClick werkt wel,
maar het resultaat verdwijnt door postBack -->
<input id="Button1" onclick="Button_Click(1);" type="button"
value="Button1" runat="server" onServerClick="SButton_Click" />
<br>
<!-- server side button zonder onServerClick -->
<input id="Button2" onClick="Button_Click(2);" type="button"
value="Button2" runat="server" />
<br>
<!-- client side button: geen onServerClick ! -->
<input id="Button3" onClick="Button_Click(3);" type="button"
value="Button3" />
</form>
<p id="label" runat="server">
</p>
<form name="form2">
<input type="text" name="tekstvak" />
</form>
</body>
</html>
Merk op dat je voor het onClick-event de functie opgeeft inclusief de haakjes en eventuele parameters (zoals Button_Click(1) ), terwijl je voor het onServerClick-event alleen de naam van de functie opgeeft. Parameters zijn daar niet toegelaten, ASP.NET kent zelf de standaard parameters toe.
Oefeningen
[bewerken]- Maak een pagina met twee invoervakken voor getallen, een knop en een label. Als er op de knop gedrukt wordt, komt in het label de som van de twee invoervakken.
- Maak een pagina met een keuzelijst met kleuren en een knop. Bij het selecteren van een kleur en het drukken op de knop krijgt de pagina-achtergrond de gekozen kleur. Om de achtergrondkleur in te stellen vervang je de <body>-tag door <body id="bodytag" runat="server">, en je zet de kleur met bodytag.Attributes("bgcolor")=kleur (waarin kleur bijvoorbeeld de waarde "green" kan hebben).
- Maak een pagina met 4 titels van cursussen die je elk kan aanvinken met een aankruisvak. Maak ook een knop met de titel "Alles". Als je op deze knop klikt, worden alle 4 titels automatisch aangekruist.
Een control dynamisch aanmaken
[bewerken]Soms wil je controls in runtime aanmaken. Het kan bijvoorbeeld zijn dat je op voorhand niet weet of je de control nodig hebt, of dat je een variabel aantal controls nodig hebt.
Dit is de code om een HtmlInputText-control toe te voegen aan een formulier met id "formulier1":
Dim ctl As HtmlInputText ctl = new HtmlInputText() ctl.ID = "Text1" ctl.Value = "Dit is mijn tekstvak" formulier1.Controls.Add(ctl)
Voorbeeld
Maak een pagina waar je een getal kan ingeven (bijvoorbeeld: het aantal kinderen). Bij het drukken op submit moeten er evenveel tekstvakken bijkomen op dezelfde pagina.
dynamisch.aspx
<%@ Page Language="VB" %>
<script runat="server">
Sub toonVakVoorKinderen(Sender As Object, E As EventArgs)
Dim n As Integer = txtAantal.Value
Dim i As Integer
For i=1 To n
Dim InputText As HtmlInputText
InputText = new HtmlInputText()
InputText.ID = "Text" & i
formulier1.Controls.Add(InputText)
Next i
End Sub
</script>
<html>
<head>
<title> Dynamisch </title>
</head>
<body>
<form id="formulier1" runat="server">
<input type="text" id="txtAantal" runat="server" ><br>
<input type="button" id="btnVerstuur" value="Versturen"
runat="server" onServerClick="toonVakVoorKinderen" />
</form>
</body>
</html>
Je kan hetzelfde soort functionaliteit ook bekomen met behulp van datacontrols, zoals de Repeater.
Een volledig overzicht over HTML-controls kan je hier vinden (Engelstalig):