Programmeren in ASP.NET/User-controls
Inleiding
[bewerken]Server-controls zijn een van de zaken die het programmeren met ASP.NET zo simpel en krachtig maken. Je hebt al gezien hoe je HTML- en web-server-controls kan gebruiken in je ASP.NET pagina's.
Wat als er nu geen control is die precies doet wat je wil?
Je kan in ASP.NET je eigen controls maken en ze gebruiken op je pagina's net zoals je de meegeleverde controls van .NET zou gebruiken.
Ook als je merkt dat je op meerdere pagina's telkens dezelfde code of HTML (of allebei) opnieuw gebruikt, kan je eraan denken om van dat onderdeel een control te maken, zodat je het steeds kan hergebruiken zonder alles opnieuw te schrijven.
Als je bijvoorbeeld een website maakt voor een boekhandel, zou je een control kunnen maken om een boek te tonen (met coverfoto, titel, auteur, enz.). Deze control kan je dan bijvoorbeeld gebruiken op een pagina over dat boek, maar ook in een lijst per auteur en in een lijst per uitgever.
Voordelen
[bewerken]Door je code in een control samen te brengen krijg je een aantal voordelen:
- je code kan gemakkelijk gebruikt worden in allerlei projecten
- je code kan eens en voor altijd getest en gedebugd worden, en ze kan daarna altijd opnieuw gebruikt worden
- je kan de control verbeteren of bijwerken, en automatisch worden alle pagina's met die control bijgewerkt
- sommige controls helpen je om een eenduidige visuele interface te voorzien voor meerdere toepassingen. Bijvoorbeeld door altijd hetzelfde soort knop te gebruiken.
- controls laten je toe het werk te verdelen over meerdere programmeurs.
- de control hoeft niet in dezelfde taal geschreven zijn als de pagina. Je kan bijvoorbeeld een control maken in C#, en hem gebruiken in een pagina met VB.
- je kan je control door anderen laten gebruiken, en zelf kan je controls van anderen gebruiken.
Soorten
[bewerken]Er zijn 3 soorten controls die je zelf kan maken:
- user-controls
- custom controls
- WebParts
De simpelste soort zijn user-controls. Deze worden gemaakt in een apart bestand, ongeveer op dezelfde manier als webformulieren. Ze kunnen ook gewone HTML-tags bevatten. Custom controls zijn meer gevorderd (ze kunnen bijvoorbeeld toegevoegd worden aan de toolbox in Visual Studio). Custom controls worden in het volgende hoofdstuk besproken. WebParts zijn controls die door de gebruiker zelf kunnen toegevoegd worden aan een pagina, en die ook door de gebruiker gewijzigd kunnen worden.
Je eerste user-control
[bewerken]In feite is er niets moeilijks aan het schrijven van een simpele user-control (soms ook een pagelet genoemd). Bijna elk onderdeel van een ASP.NET pagina kan gebruikt worden als een user-control.
Kies in Visual Web Developer in het menu File - New File - Web User Control, en geef als naam basic.ascx (vermijd spaties of punten in de bestandsnaam). Voeg de volgende code toe:
basic.ascx
<%@ Control Language="VB" ClassName="basic" %> <p> Dit is een user-control... ja hoor! </p>
Dat is alles. Wat hierboven staat kan gemakkelijk gebruikt worden als een user-control.
Toegegeven, er gebeurt niet veel, maar het illustreert wel dat deze controls zeer simpel kunnen zijn. Let op de .ascx-extensie. ASCX is de gebruikelijke extensie die aan pagina's gegeven wordt als ze moeten werken als een control. Het zorgt voor duidelijkheid en .ascx bestanden worden beschermd tegen directe uitvoering door de webserver, zodat de gebruiker nooit de code kan downloaden.
Nu je een user-control gemaakt hebt, is hier een voorbeeld hoe je die kan gebruiken in een ASP.NET web pagina.
basic.aspx
<%@ Page Language="VB" %> <%@ Register TagPrefix="wikibooks" TagName="basic" Src="basic.ascx" %> <html> <head> <title>ASP.NET User-control voorbeeld - Basic</title> </head> <body> <wikibooks:basic runat="server" /> </body> </html>
De pagina hierboven geeft een standaard HTML-pagina met de tekst binnen onze user-control in plaats van in de tag van de user-control.
Opmerkingen
- In Visual Studio kan je de user-control ook in de pagina zetten door het ascx-bestand vanuit de Solution Explorer (rechterpaneel) op de pagina te slepen.
- Een user-control wordt gecompileerd net zoals een aspx-bestand, dit is tijdens de eerste uitvoering.
Hoe werkt het toevoegen van een user-control?
Het bijzondere zit hier in het "Register"-directief. Om dit te gebruiken moet je drie attributen opgeven:
TagPrefix | definieert de prefix die gebruikt moet worden in de tags waar de controls komen. Je mag de standaard <uc0:xxxx> gebruiken, of je eigen tags kiezen. |
TagName | bepaalt de naam waarmee de control zal aangeduid worden. Deze naam mag nog niet bestaan binnen de namespace, maar je mag hem zelf kiezen. Het is het beste om een naam te kiezen die aangeeft wat de control ongeveer doet. |
Src | verwijst naar de code waar de control gedefinieerd wordt. Hierbij wordt een virtueel pad gebruikt, dus de waarde moet zoiets zijn als "control.ascx" of "/path/control.ascx" of “~/controls/control.ascx” en niet een absoluut pad zoals "C:\path\control.ascx." |
Eenmaal je het "Register"-directief hebt toegevoegd, is de control geregistreerd en kan hij gebruikt worden net zoals elke andere server-control. Je geeft de TagPrefix en TagName op in de tag van de control, net zoals je dat zou doen met een ingebouwde control. Controleer alleen nog of je het runat="server"-attribuut hebt, en je bent klaar. Hier is de simpelste vorm voor een user-control-tag:
<TagPrefix:TagName runat="server" />
Je kan meerdere user-controls op één pagina zetten. Het "Register"-directief moet je maar éénmaal toevoegen, maar elke user-control krijgt dan een andere user-control-tag. Je geeft ze dan ook best een ID, en die moet natuurlijk voor elke control verschillend zijn.
Oefeningen
[bewerken]- Maak een user-control die de datum op het scherm zet.
- Maak een user-control die een willekeurig getal op het scherm zet. Gebruik Rnd(10).
- Maak een "klok" user-control, die de tijd toont (en die verder tikt). Zet hiervoor in het HTML-gedeelte van de user-control een JavaScript.
- Maak een user-control "teller" die toont hoe dikwijls de pagina al bezocht werd. Gebruik het HttpApplicationState-object.
Eigenschappen geven aan je control
[bewerken]Tot nu doet je control nog niet veel meer dan code uit een apart bestand halen. Gelukkig houdt het hier niet op.
Eigenschappen (property's) kan je vergelijken met variabelen die behoren tot de control. In .NET gebruik je voor property's speciale zogenaamde accessormethodes (ook getters en setters genoemd).
Nu maak je een nieuwe control met een label, en voeg je twee property's toe, één voor de kleur en één voor de tekst.
properties.ascx
<%@ Control Language="VB" ClassName="properties" %> <script runat="server"> Private _kleur As String = "black" Public Property Kleur as String Get Return _kleur End Get Set (Value As String) _kleur = Value Label1.ForeColor = System.Drawing.Color.FromName(_kleur) End Set End Property Private _tekst as String = "Dit is een user-control!" Public Property Tekst as String Get Return _tekst End Get Set (Value As String) _tekst = Value Label1.Text = _tekst End Set End Property </script> <p> <asp:Label id="Label1" runat="server"></asp:Label> </p>
Standaard ziet de control er nog hetzelfde uit, maar je kan nu wel de kleur en de tekst van de control wijzigen. Dat kan op 2 manieren, rechtstreeks in de tag, of via code (op voorwaarde dat de control een id-attribuut heeft waardoor je er kan naar verwijzen). Merk ook op dat de control meerdere malen gebruikt wordt, en dat elke instantie afzonderlijk kan ingesteld worden.
properties.aspx
<%@ Page Language="VB" %> <%@ Register TagPrefix="wikibooks" TagName="properties" Src="properties.ascx" %> <script language="VB" runat="server"> Sub Page_Load(Sender as Object, E as EventArgs) UserCtrl1.Kleur = "green" UserCtrl1.Tekst = "De property's van deze control werden via code ingesteld!" End Sub </script> <html> <head> <title>ASP.NET User-control voorbeeld - Property's</title> </head> <body> <wikibooks:properties runat="server" /> <wikibooks:properties Kleur="red" runat="server" /> <wikibooks:properties Tekst="Dit is wel tof!" runat="server" /> <wikibooks:properties Kleur="blue" Tekst="Niet?" runat="server" /> <wikibooks:properties id="UserCtrl1" runat="server" /> </body> </html>
Opmerkingen
- Je kan ook methodes toevoegen aan een user-control. Als je deze methodes publiek maakt, dan kan je ze gewoon vanuit de pagina oproepen.
- Publieke properties van je user control verschijnen automatisch in het Property Panel van Visual Studio, en ook intellisense gebruikt ze.
- Je kan op deze manier zelfs een control maken zonder visuele onderdelen (zonder html), met enkel een of meerdere methodes. Het voordeel is dat je die methodes dan in meerdere pagina's kan toevoegen en gebruiken.
Oefeningen
[bewerken]- Maak een user-control met een dropdownlist, waarin alle landen staan. Maak ook een property die het geselecteerde land geeft.
- Maak een user-control die een afbeelding toont met een rollover-effect. Maak hiervoor eigenschappen "ImageURL1" en "ImageURL2".
- Maak een user-control die een afbeelding toont, maar als de afbeelding niet gevonden wordt, moet er een boodschap verschijnen "foto niet beschikbaar" (in de plaats van een leeg kader). Gebruik de methode System.IO.File.Exists("naambestand") om te testen of het bestand bestaat. "naambestand" moet een absoluut pad bevatten, gebruik Server.MapPath() om dat pad te vinden.
- Maak een user-control "adres", dat een adres toont uit de Adressendatabank. Geef de control een property "AdresID", die verwijst naar de ID van het adres in de tabel. De control moet zelfstandig de gegevens uit de databank halen (hierdoor staat de control meer op zichzelf, een goed voorbeeld van object-georiënteerd programmeren).
- Maak een user-control waarmee de gebruiker een datum kan kiezen. Gebruik 3 dropdownlists (dag, maand, jaar). Maak een property "SelectedDate".
- Maak een user-control die een balkgrafiek maakt door een bepaalde afbeelding n maal te herhalen. n is een property van de user-control.
- Maak een "getalvak", dit is een tekstvak dat alleen getallen accepteert. Gebruik een validator, en zorg er ook voor dat de invoer rechts uitgelijnd is. Maak een property "Waarde".
Een control events laten verwerken
[bewerken]Je kan een control bijna alles laten doen wat je maar wil. In de volgende code zal de control het OnClick-event van een knop verwerken. Met dit soort gebeurtenisverwerking (event handling) kan je controls schrijven die bijna geen code in de pagina meer nodig hebben. De controls kunnen hun gebeurtenissen zelfstandig verwerken.
Deze control bevat een tekstvak-web-control en een knop. De control is zo gemaakt dat het getal in het tekstvak verhoogt als je op de knop drukt.
events.ascx
<%@ Control Language="VB" %> <script runat="server"> Public Property Waarde as Integer Get Return CInt(tbGetal.Text) End Get Set tbGetal.Text = CStr(Value) End Set End Property Sub btnUp_Click (Src as Object, E as EventArgs) Waarde = Waarde + 1 End Sub </script> Getal: <asp:textbox id="tbGetal" runat="server" /> <asp:Button ID="btnUp" runat="server" OnClick="btnUp_Click" Text="Up"></asp:Button>
events.aspx
<%@ Page Language="VB" %> <%@ Register TagPrefix="wikibooks" TagName="events" Src="events.ascx" %> <html> <head> <title>ASP.NET User-control voorbeeld - Validering & Events</title> </head> <body> <form runat="server"> <wikibooks:events id="events1" runat="server" Waarde="0" /> </form> </body> </html>
Oefeningen
[bewerken]- Maak een user-control die werkt zoals een checkbox, maar die dubbel zo groot is. Doe dit door je eigen afbeeldingen te gebruiken voor "aangekruist" en "niet aangekruist".
- Maak een control die samengesteld is uit een keuzelijst en twee knoppen "omhoog" en "omlaag". Als de gebruiker een keuze maakt en op "omhoog" klikt, dan moet het item omhoog schuiven in de lijst. Maak ook een property "Items", zodat vanuit de pagina de lijst van items kan opgevraagd worden in de volgorde die de gebruiker dan ingesteld heeft.
- Maak een user-control waarmee de gebruiker een datum kan kiezen. Gebruik 3 dropdownlists (dag, maand, jaar) en een Calendar-control. Zorg dat beide altijd dezelfde datum aangeven. De gebruiker kan dan zowel de dropdownlists als de Calendar gebruiken.
Eigen events opwekken vanuit een user-control
[bewerken]In het vorige voorbeeld verwerkte de user-control zelf de events van de knop. Meestal wil je toch ook de pagina hiervan op de hoogte brengen. Om dat te doen moet de user-control zelf een nieuw event "opwekken" waarop de pagina kan reageren.
Het volgende voorbeeld toont een user-control, events2, die een custom event opwekt, Change, telkens als het cijfer verhoogt.
Dit wordt als volgt gedaan:
- Het eigen Change-event wordt gedeclareerd met het standaard eventpatroon. (Dit patroon bevat de definitie van een protected OnChange-methode die het Change-event opwekt.)
Public Event Change(Sender as Object, E as EventArgs) Protected Sub OnChange(e As EventArgs) RaiseEvent Change(Me, e) End Sub
- Het OnClick-event van btnUp bestond al. Hierin wekken we nu ook het Change-event op door de OnChange-methode aan te roepen.
Private Sub btnUp_Click(sender As Object, e As EventArgs) Waarde = Waarde + 1 OnChange(EventArgs.Empty) End Sub
Het Change-event kan verwerkt worden door een pagina die de control bevat, zoals in het volgende voorbeeld getoond wordt. Je moet wel zelf de event-handler aanmaken en koppelen aan de control. In het voorbeeld voorziet de pagina een event-handling-methode voor het Change-event, waarin een boodschap getoond wordt in een label.
events2.ascx
<%@ Control Language="VB" %> <script runat="server"> Public Property Waarde as Integer Get Return CInt(tbGetal.Text) End Get Set tbGetal.Text = CStr(Value) End Set End Property Sub btnUp_Click (Sender as Object, E as EventArgs) Waarde = Waarde + 1 OnChange(EventArgs.Empty) End Sub Public Event Change(Sender as Object, E as EventArgs) Protected Sub OnChange(e As EventArgs) RaiseEvent Change(Me, e) End Sub </script> Getal: <asp:textbox id="tbGetal" runat="server" /> <asp:Button ID="btnUp" runat="server" OnClick="btnUp_Click" Text="Up"></asp:Button>
In de pagina hieronder wordt de control gebruikt, en het Change-event wordt verwerkt:
events2.aspx
<%@ Page Language="VB" %> <%@ Register TagPrefix="wikibooks" TagName="events" Src="events2.ascx" %> <script runat="server"> Sub events1_Change(Sender as Object, E as EventArgs) Label1.Text = "het getal werd verhoogd" ' doe verdere verwerking hier, bijvoorbeeld databank bijwerken End Sub </script> <html> <head> <title>ASP.NET User-control voorbeeld - Validering & Events</title> </head> <body> <form runat="server"> <wikibooks:events id="events1" runat="server" Waarde="0" OnChange="events1_Change" /><br> <asp:Label id="Label1" runat="server" Text=""></asp:Label> </form> </body> </html>
Oefeningen
[bewerken]- Voor elk van de drie vorige oefeningen, zorg ervoor dat de pagina een event krijgt bij een wijziging in de user-control.