Programmeren in ASP.NET/Custom controls

Uit Wikibooks

Programmeren in ASP.NET

  1. Wat is ASP.NET?
  2. Wat heb ik nodig voor ASP.NET?
  3. Een ASP.NET-server installeren
  4. Je eerste ASP.NET-pagina
  5. HTML-controls
  6. Foutzoeken
  7. Web-server-controls
  8. Webformulieren
  9. Veelgebruikte objecten
  10. Validering
  11. Master-pagina's
  12. Navigatie
  13. Gegevenstoegang
  14. Werken met databanken
  15. Databankgegevens wijzigen
  16. Werken met datacontrols
  17. GridView
  18. FormView en DetailsView
  19. User-controls
  20. Custom controls
  21. AJAX
  22. Viewstate
  23. Configuratiebestanden
  24. Webservices
  25. Beveiliging
  26. Personalisatie en profielen
  27. Thema's en skins
  28. WebParts
  29. Globalisering
  30. Caching
  31. Mail vanuit ASP.NET
  32. Reguliere expressies
  33. Server-side afbeeldingen
  34. Mobiele toepassingen
  35. Meer informatie
  36. Appendix: foutmeldingen

Inleiding[bewerken]

Custom controls zijn gecompileerde controls die door de programmeur zelf ontworpen worden en die werken zoals web-controls.

Ze hebben meer mogelijkheden dan de simpele user-controls uit het vorige hoofdstuk:

  • Ze kunnen toegevoegd worden aan de Toolbox in Visual Web Developer
  • Je kan hun eigenschappen rechtstreeks instellen in de editor (met het property-paneel)
  • Ze kunnen gebruikt worden zonder de broncode
  • Ze kunnen gedeeld worden tussen verschillende applicaties op dezelfde server.

Custom controls kunnen op drie manieren gemaakt worden:

  1. door een bestaande control als basis te nemen en daarvan een nieuwe custom control af te leiden (bv. door een gespecialiseerd tekstvak af te leiden van asp:textbox). Dit noemt men een derived custom control.
  2. door een nieuwe custom control samen te stellen uit twee of meer bestaande controls. Dit noemt men composite custom control.
  3. door een nieuwe custom control te maken vanaf nul (afgeleid van de basis control klasse Webcontrol of Control) Dit noemt men een full custom control.

Opmerking:

  • Wanneer je custom controls gebruikt in Visual Web Developer, dan is een aantal extra "designer"-methodes nodig om de control ook te laten werken in de editor zelf. Dit zorgt ervoor dat de control er al min of meer als zichzelf uitziet in de editor (anders krijg je alleen een weinig zeggend label). In deze cursus worden deze methodes niet besproken. Zonder deze methodes werkt de control normaal als je hem test vanaf een website, hij werkt alleen niet binnen de editor.

Een simpele custom control maken[bewerken]

In het vorige hoofdstuk zag je dat je voor een user-control een .ascx-bestand gebruikt. Voor een custom control maak je een .vb-bestand (of .cs als je met C# werkt). Alles wat je moet doen om een simpele custom control te maken is een klasse aanmaken die afgeleid is van Control (of WebControl) en de Render()-methode daarvan te overschrijven. De Render()-methode heeft één argument van type System.Web.UI.HtmlTextWriter. De HTML die je control naar de client wil sturen moet doorgegeven worden als een string naar de Write()-methode van HtmlTextWriter.

Kies File-New File in Visual Web Developer, en kies vervolgens Class en geef het bestand de naam simpel.vb. Merk op dat er voor dit bestand een folder App_Code aangemaakt wordt. Alle custom controls (en klasses) komen automatisch in deze folder terecht.

Het volgende voorbeeld toont een simpele control die een boodschapstreng rendert.

simpel.vb

Imports System
Imports System.Web
Imports System.Web.UI

Namespace Wikibooks
    Public Class Simpel : Inherits Control

       Protected Overrides Sub Render(writer As HtmlTextWriter)
           writer.Write("<H2>Welkom bij Wikibooks!</H2>")
       End Sub

    End Class
End Namespace

In de pagina moet je nu de control registreren ongeveer zoals bij een user control. Je moet een TagPrefix opgeven en een Namespace. De control wordt automatisch opgezocht in de folder App_Code via de namespace.

simpel.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="cc1" Namespace="Wikibooks" %>

<html>
   <head>
      <title>Simpele custom control</title>
   </head>
   <body>
      <form runat="server">
          <cc1:Simpel id="MijnControl" runat=server/>
      </form>
   </body>
</html>

Een assembly maken[bewerken]

Om een control aan de toolbox toe te voegen moet hij eerst gecompileerd worden. Bij het compileren wordt de code omgezet in een zogenaamd assembly-bestand met extensie .dll (dynamic link library) in de bin-folder.

Maak een tekstbestand en noem het maaksimpel.bat.

maaksimpel.bat

SET source=App_Code\simpel.vb
SET target=bin\EenvoudigeControls.dll
SET assemblies=system.dll,system.web.dll
SET compiler=%WINDIR%\Microsoft.NET\Framework\v2.0.50727
MKDIR bin
%COMPILER%\vbc /t:library /out:%target% /r:%assemblies% %source%
PAUSE

(controleer wel of de versie van het framework 2.0.50727 overeenstemt met die op jouw server)

Hierin is:

source de naam van het bronbestand met de code
target de naam (en het pad) van de assembly die moet gemaakt worden
assemblies de modules die je nodig hebt om de code te compileren (als je bijvoorbeeld ook databanken gebruikt, moet je hier nog system.data.dll aan toevoegen). In de Helpmodule van je editor kan je opzoeken tot welke assembly een bepaald object behoort.
compiler de locatie van de Visual Basic compiler (vbc.exe) op jouw computer
pause niet verplicht, maar zorgt ervoor dat het venster niet onmiddellijk sluit, zodat je eventuele fouten nog kan lezen.

Dubbelklik in Windows Explorer op dit bestand om het uit te voeren. Het programma vbc (Visual Basic Compiler) zal nu het bestand simpel.vb compileren en de uitvoer EenvoudigeControls.dll wordt in een subfolder "bin" geplaatst. Eventuele fouten worden gemeld.

Onthoud dat telkens je wijzigingen aanbrengt in simpel.vb, je het bestand opnieuw moet compileren.

Voor andere compilaties moet je maaksimpel.bat kopiëren en aanpassen. Stel iedere keer "source" en "target" in op de juiste waarde.

Pas nu simpel.aspx aan, zodat die met de assembly werkt, en niet met de code in App_Code. De referentie Assembly="EenvoudigeControls" in simpel.aspx moet verwijzen naar deze assembly (zonder de DLL-extensie, en zonder bin). Verwijder het bestand simpel.vb uit de App_Code-folder, anders krijg je nu een conflict.

simpel.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="cc1" Namespace="Wikibooks" 
    Assembly="EenvoudigeControls" %>

<html>
   <body>
      <form method="POST" action="Simpel.aspx" runat=server>
          <cc1:Simpel id="MijnControl" runat=server/>
      </form>
   </body>
</html>

ASP.NET zoekt automatisch naar alle dll's in de bin-folder (en alleen daar).

Eenmaal de control gecompileerd is kan je hem toevoegen aan de toolbox in Visual Studio. Klik rechts op de toolbox, en kies "Choose items...". Blader naar je dll en voeg hem toe.

Als je deze control nu in een ander project op een pagina sleept, zal Visual Studio automatisch op dat moment de dll ook kopiëren naar de bin-folder van die applicatie.

Let op: als je achteraf de dll wijzigt, moet je de bijgewerkte dll zelf kopiëren naar de applicaties die ze gebruiken.

Eenvoudige property's geven aan de control[bewerken]

We werken hier weer met getters en setters omdat ze toelaten data te verbergen en ze worden ondersteund door visuele designers zoals Visual Studio.

Het volgende voorbeeld toont hoe je simpele property's toevoegt. Het voorbeeld maakt een property Grootte met het type Integer.

simpelproperty.vb

Imports System
Imports System.Web
Imports System.Web.UI

Namespace Wikibooks

    Public Class SimpelProperty : Inherits Control    

        Private _grootte As Integer

        Public Property Grootte As Integer
           Get
               Return _grootte
           End Get
           Set
               _grootte = Value
           End Set
        End Property

        Protected Overrides Sub Render(writer As HtmlTextWriter)
            writer.Write("<H" & _grootte & ">Wikibooks</H" & _grootte & ">")
        End Sub

    End Class
End Namespace

simpelproperty.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="cc1" Namespace="Wikibooks" %>

<html>
   <head>
      <title>Simpele custom control</title>
   </head>
   <body>
      <form runat="server">
          <cc1:SimpelProperty Grootte="3" runat="server" />
      </form>
   </body>
</html>

Als je deze control toevoegt aan je pagina, dan kan je de property Grootte terugvinden in het Property Panel.

Oefeningen[bewerken]

  1. Maak een control die een horizontale balkgrafiek produceert door een afbeelding te herhalen of uit te rekken. De lengte van de grafiek is een property.

Een samengestelde control maken[bewerken]

Je kan nieuwe controls ontwerpen door bestaande controls samen te voegen. Een typisch voorbeeld is een zogenaamde "spin"- of "up-down"-control. Dit is een control waar je een getal kan invoeren door het in te tikken, of door het in te stellen met twee knoppen: "omhoog" en "omlaag". Deze control bestaat uit 3 bestaande controls: één invoervak en twee knoppen.

Samengestelde controls komen overeen met user-controls die ontworpen worden met ASP.NET-pagina-syntax. Het grootste verschil tussen user-controls en samengestelde controls is dat user-controls bewaard worden als .ascx tekstbestanden, terwijl samengestelde controls gecompileerd worden en daarna bewaard worden in assembly's.

De stappen in het ontwerp van een samengestelde control zijn:

  • Overschrijf de CreateChildControls-methode (overgeërfd van Control) om instanties aan te maken van de benodigde child-controls en voeg deze instanties toe aan de Controls-collectie.
  • Als je samengestelde control meerdere keren kan voorkomen op dezelfde pagina, en je control bevat bijvoorbeeld een tekstvak, dan bestaat er het gevaar dat je op die pagina meerdere tekstvakken krijgt met dezelfde ID. Om dit te vermijden moet je de System.Web.UI.INamingContainer-interface implementeren (zie het voorbeeld hieronder). Wanneer die interface wordt gebruikt door een control, zal het ASP.NET-pagina-framework automatisch nieuwe namen geven aan de child-controls.

Je moet de Render()-methode hier niet overschrijven, omdat de child-controls de rendering voor hun rekening nemen. Je kan property's maken die op hun beurt property's van de child controls bepalen.

Het volgende voorbeeld maakt een samengestelde control, Samengesteld1, die een LiteralControl combineert met een TextBox. Samengesteld1 stelt een eigen property, Waarde, van type Integer, ter beschikking die een string doorsluist van en naar de Text-property van TextBox.

samengesteld1.vb

Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace Wikibooks

    Public Class Samengesteld1 : Inherits Control : Implements INamingContainer

        Public Property Waarde As String
           Get
               Me.EnsureChildControls()
               Dim tb1 As TextBox = Me.FindControl("tb1")
               Return tb1.Text
           End Get
           Set
               Me.EnsureChildControls()
               Dim tb1 As TextBox = Me.FindControl("tb1")
               tb1.Text = Value
           End Set
        End Property

        Protected Overrides Sub CreateChildControls()

            ' maak hier de child-controls aan
            Dim lbl1 As New Label()
            lbl1.Text = "Waarde"
		  Me.Controls.Add(lbl1)

            Dim tb1 As New TextBox()
            tb1.Text = "0"
            tb1.ID="tb1"
            Me.Controls.Add(box)

        End Sub

    End Class

End Namespace

samengesteld1.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="cc1" Namespace="Wikibooks"  %>
<script language="VB" runat=server>
      Private Sub VerhoogBtn_Click(Sender As Object, E As EventArgs)
          MijnControl.Waarde = MijnControl.Waarde + 1
      End Sub
</script>
<html>
   <head>
      <title>Samengestelde custom control</title>
   </head>
   <body>
      <form runat="server">
          <cc1:Samengesteld1 id="MijnControl" Waarde="0" runat="server" />
          <br>
          <asp:button text="Verhoog" OnClick="VerhoogBtn_Click" runat=server/>
      </form>
   </body>
</html>

Oefening[bewerken]

  1. Maak een nummervak-control, dit is een tekstbox waar je alleen cijfers kan invullen. Gebruik een tekstvak samen met een validatorcontrol. Zorg ook dat het cijfer rechts uitgelijnd is.

Events verwerken in een samengestelde control[bewerken]

Een samengestelde control kan events verwerken die veroorzaakt worden door zijn child controls. Dit gebeurt door event handling-methodes te voorzien voor de events die door de child controls opgewekt worden.

In de volgende samengestelde control, Samengesteld2, zit de verhoogknop in de samengestelde control zelf. Daarom moet de samengestelde control ook zelf de event handling-methode voorzien voor het Click-event van de knop. Deze methode verhoogt de property Waarde van Samengesteld2.

Je kan deze handler niet koppelen aan de knop op de normale manier, met een OnClick-attribuut in de tag, want er zijn hier geen tags. In de plaats daarvan wordt AddHandler gebruikt in de CreateChildControls()-methode. Het eindresultaat is een control die zijn eigen eventverwerking doet. Wanneer de Verhoog knop aangeklikt wordt, wordt de waarde in het tekstvak verhoogd.

samengesteld2.vb

Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace Wikibooks

    Public Class Samengesteld2 : Inherits Control : Implements INamingContainer

       Public Property Waarde As Integer
          Get
             Me.EnsureChildControls()
             Dim tb As TextBox = CType(Me.FindControl("tb1"),TextBox)
             Return CInt(tb.Text)
          End Get
          Set
             Me.EnsureChildControls()
             Dim tb As TextBox = CType(Me.FindControl("tb1"),TextBox)
             tb.Text = CStr(Value)
          End Set
       End Property

        Protected Overrides Sub CreateChildControls()

            Dim tb As New TextBox()
            tb.Text="0"
            tb.Style("text-align")="right"
            tb.ID="tb1"
            Me.Controls.Add(tb)

            Dim btn As New Button()
            btn.Text="Verhoog"
            Me.Controls.Add(btn)

            AddHandler btn.Click, AddressOf btn_Click

        End Sub

        Private Sub btn_Click(Sender As Object,e As EventArgs)
            Dim tb As TextBox = CType(Me.FindControl("tb1"),TextBox)
            tb.Text = tb.Text + 1
        End Sub

    End Class
End Namespace

samengesteld2.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="cc1" Namespace="Wikibooks" %>

<html>
   <head>
      <title>Samengestelde custom control</title>
   </head>
   <body>
      <form runat="server">
          <cc1:Samengesteld2 id="MijnControl" Waarde="0" runat=server/>
      </form>
   </body>
</html>

Oefeningen[bewerken]

  1. Maak een uitklapbaar panel. Normaal zie je een linkbutton "meer info". Als je erop klikt, zie je meer informatie en verandert de link in "minder info".

Eigen events opwekken vanuit een samengestelde control[bewerken]

In het vorige voorbeeld verwerkte de samengestelde control zelf de events van zijn child-controls. Misschien wil je ook in de pagina deze events nog verder verwerken, of wil je een nieuw event maken waarop de pagina kan reageren.

Een samengestelde control kan eigen events hebben, die de control zelf opwekt als gevolg van events die door zijn child controls doorgegeven worden.

Het volgende voorbeeld toont een samengestelde control, Samengesteld3, die een custom event opwekt, Change, als antwoord op de Click-event van de Button-child-control.

Net zoals we reeds zagen bij de user-control, voeg je een Change-event toe, en een protected OnChange-methode. Verder roep je OnChange op als er op de knop geklikt wordt.

samengesteld3.vb

Imports System
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace Wikibooks

    Public Class Samengesteld3 : Inherits Control : Implements INamingContainer

       Public Property Waarde As Integer
          Get
             Me.EnsureChildControls()
             Dim tb As TextBox = CType(Me.FindControl("tb1"),TextBox)
             Return CInt(tb.Text)
          End Get
          Set
             Me.EnsureChildControls()
             Dim tb As TextBox = CType(Me.FindControl("tb1"),TextBox)
             tb.Text = CStr(Value)
          End Set
       End Property

        Protected Overrides Sub CreateChildControls()

            Dim tb As New TextBox()
            tb.Text="0"
            tb.Style("text-align")="right"
            tb.ID="tb1"
            Me.Controls.Add(tb)

            Dim btn As New Button()
            btn.Text="Verhoog"
            Me.Controls.Add(btn)

            AddHandler btn.Click, AddressOf Button1_Click

        End Sub

        Private Sub Button1_Click(Sender As Object,e As EventArgs)
            Dim tb As TextBox = CType(Me.FindControl("tb1"),TextBox)
            tb.Text = tb.Text + 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

    End Class
End Namespace

samengesteld3.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="cc1" Namespace="Wikibooks" %>

<script language="VB" runat=server>

      Private Sub Samengesteld_Change(Sender As Object, E As EventArgs)
         Label1.Text = "De waarde is veranderd!"
      End Sub

</script>

<html>
   <head>
      <title>Samengestelde custom control</title>
   </head>
   <body>
      <form runat="server" >
          <cc1:Samengesteld3 id="MijnControl" Waarde="0"
			OnChange="Samengesteld_Change" runat=server/>
          <asp:Label id="Label1" runat="server" />
      </form>
   </body>
</html>

Als je deze control toevoegt aan de toolbox in Visual Studio, komt het Change-event ook te voorschijn in de lijst met events die bij de control horen.

Oefeningen[bewerken]

  1. Maak een custom 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".

Custom controls downloaden[bewerken]

Op het Internet kan je custom controls vinden die je kan downloaden en zelf installeren op je toolbox. Sommige zijn gratis, anderen niet.

Een goede plaats om te zoeken is www.asp.net en vervolgens klikken op "Resources" en "Control Gallery".


← User-controls Programmeren in ASP.NET AJAX →
Informatie afkomstig van https://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.