# Programmeren in ASP.NET/Werken met datacontrols
## Datacontrols

In ASP.NET zijn er zes controls die speciaal gemaakt zijn voor het tonen van gegevens uit databanken:
Deze controls hebben al een hoop functionaliteit ingebouwd, waardoor veel taken erg simpel worden.

## Repeater
### Databinding met een Repeater-control

De Repeater is de eenvoudigste datacontrol. Een Repeater is ideaal als de gegevens alleen moeten weergegeven worden.
Hier is een voorbeeld:
repeater.aspx
Wat gebeurt er in deze pagina?
* tijdens het Page_PreRender-event worden de gegevens uit de databank gehaald door de DataSource-control, en deze wordt met databinding gekoppeld aan de repeater.
* De gegevens worden in de Repeater getoond met behulp van de speciale databindingsyntax <%# Eval("Naam") %>. Op de plaats van deze tag komt de waarde uit de databank te staan.
* Deze gegevens staan binnen een <ItemTemplate>-tag.
Merk op dat alle code en HTML weer gescheiden zijn. Alleen de databinding-resultaten staan nog in de HTML-sectie met de syntax (met het hekje).
Opmerking Je kan gegevens zoals getallen en datums formatteren met deze syntax:
(in dit voorbeeld krijg je een korte datum zonder het uur).
Zie voor de verschillende formatteringscodes.

## Syntax voor data-binding

Met ASP.NET is er een nieuw soort syntax voor het inbrengen van gegevens in de HTML-sectie van een document via data-binding. Deze syntax gebruikt het hekje: <%#...%>
Hier zijn enkele voorbeelden:
Deze syntax lijkt erg op de korte ASP-syntax voor renderblokken (<%= %>), maar het gedrag is toch heel anders. Terwijl de renderblokken worden geëvalueerd op het moment dat de pagina verwerkt wordt, zal de ASP.NET-databindingsyntax alleen geëvalueerd worden wanneer de DataBind-methode aangeroepen wordt.
DataBind is een methode van Page en van alle server-controls. In ASP.NET 2.0 hoef je deze methode niet zelf aan te roepen als de datacontrol gekoppeld is aan een DataSource-control (AccessDataSource of SQLDataSource). De methode wordt vanzelf uitgevoerd tijdens Page_Load of Page_PreRender.
Als je DataBind oproept voor een bepaalde control, dan wordt dit ook doorgegeven aan alle kinderen van die control. Zo zal DataList1.DataBind de DataBind-methode oproepen voor elke control in de DataList-templates (meer over de DataList-control in de paragrafen hieronder). Het oproepen van DataBind op de pagina – Page.DataBind of gewoon DataBind – zorgt ervoor dat alle databinding-expressies op de pagina geëvalueerd worden.
DataBind wordt gewoonlijk opgeroepen in twee gevallen:
* vanuit het Page_Load-event of Page_Prerender-event
* nadat de gegevens gewijzigd werden (bijvoorbeeld omdat je updates gedaan hebt)
Opmerkingen:
* De databinding-expressie zoals in de voorbeelden hierboven moet als resultaat een waarde van het type String geven. Indien nodig moet je zelf de omzetting doen. Bijvoorbeeld, als datum een datum is:
* Je mag code die moet uitgevoerd worden niet in dit blok plaatsen (zoals assignments, voorwaarden of lussen). Alleen specifieke databindingexpressies die een resultaat teruggeven mogen binnen dit blok gebruikt worden. Functies die een waarde teruggeven mogen dus wel.
* In de praktijk haal je de gegevens voor een datacontrol meestal uit een databank, maar in feite kunnen deze controls ook hun gegevens krijgen van een gewone array. Het principe wordt getoond in de volgende code:
* Als je als datasource een XmlDataSource gebruikt, dan vervang je Eval door XPath:

### Zoeken met een Repeater

Soms wil je alleen maar de adressen uit een bepaalde gemeente laten zien. De gebruiker kan deze gemeente invullen in een tekstvak tbGemeente.
Om dit te bekomen moet je een WHERE-conditie opnemen in de datasource. Dit kan je doen via de wizard. We deden dit vroeger ook al bij lijsten met parameters. Stel de WHERE-conditie zo in dat het veld Gemeente moet overeenkomen met de waarde in de control tbGemeente (het tekstvak). Automatisch wordt deze tekst dan als parameter gebruikt bij het opvragen van de gegevens.
Je kan zelfs meer dan één WHERE-conditie gebruiken als je wil.

### Oefeningen

* Breid de pagina repeater.aspx uit met een zoekfunctie: laat de gebruiker een gemeente ingeven, en toon alleen de adressen uit die gemeente.
* Maak een pagina waar je de gemeentes kan opzoeken met een bepaalde postcode.
* Zorg ervoor dat de tabel ook een veld met het e-mailadres bevat. Toon het e-mailadres met de repeater, maar zodanig dat je er kan op klikken (met mailto:).
* Maak een tabel met gebeurtenissen en datums. Maak een pagina met 2 Calendar-controls, waar alle gebeurtenissen tussen die 2 datums getoond worden.

## Templates gebruiken

De repeater heeft in totaal 5 templates om gegevens te tonen. (De DataList en de DataGrid hebben nog 2 extra templates, zie verder)
* Het ItemTemplate wordt getoond voor elke rij in de data-source van de repeater.
* Het AlternatingItemTemplate wordt getoond voor alle even rijen. Hiermee kan je bijvoorbeeld kleuren laten wisselen voor elke rij. Indien dit template ontbreekt, dan wordt voor alle items het ItemTemplate gebruikt.
* Het HeaderTemplate wordt eenmaal getoond bovenaan de control. Je kan deze template gebruiken om titels te tonen.
* Het SeparatorTemplate wordt getoond tussen de rijen. Als er maar 1 record is, wordt het niet getoond.
* Het FooterTemplate wordt eenmaal getoond onderaan de control. Soms kan je hier bijvoorbeeld totalen tonen.
Alleen het ItemTemplate is altijd verplicht. De andere zijn optioneel.
Je kan alleen databinding uitvoeren in het ItemTemplate en het AlternatingItemTemplate.
Binnen elk van deze templates kan je verder eender welke HTML-tags gebruiken, en ook HTML-controls en servercontrols zijn toegelaten.
Enkele voorbeelden:
Met een Label-control:
In de vorm van een tabel:
Met een alternerende kleur:
Met een hyperlink:

## DataList
### Gegevens ophalen met een DataList-control

Een tweede veelgebruikte control is de datalist-control. Deze control kan alles wat de Repeater kan, maar bovendien kan je met een DataList gegevens selecteren, wijzigen, verdelen in meerdere kolommen, enz.
In het eerste voorbeeld hieronder wordt een datalist-control gebruikt voor het tonen van gegevens alleen. Bij het aanmaken van de databankconnectie met de wizard wordt voor elk veld automatisch een label toegevoegd aan het ItemTemplate.
Bij een datalist kan je templates toevoegen door in de smart tag "Edit templates" te kiezen. Sleep een Label-control op het ItemTemplate en kies in de smart tag van het Label dan weer "Edit Databindings". Klik op "Refresh Schema" als de lijst met velden grijs is. Je kan ook een "custom binding" instellen voor de Text-property met deze waarde: Eval("Naam"). Merk op dat je ook andere eigenschappen van het label kan instellen met databinding.
datalist.aspx
Opmerkingen:
* Een datalist heeft veel meer mogelijkheden dan een repeater. Enkele worden in de volgende paragrafen besproken.
* In tegenstelling tot de repeater laat de datalist-control toe dat je de verschillende templates rechtstreeks kan aanpassen in Visual Studio. Je doet dit door rechts te klikken op de datalist en te kiezen voor "Edit templates...".
* Ook het "Property Builder"-venster bevat uitgebreide opties om op een eenvoudige manier de datalist in te stellen.
* Als je de opmaak wilt aanpassen, selecteer dan de DataList component in Visual Studio, en klik op de "Auto Format..."-link in de Smart Tag opties.

### DataList met een alternerende kleur

Net zoals bij een repeater kan je een alternerende opmaak kiezen voor elk tweede item in de lijst. Bij een DataList echter is het dikwijls voldoende een AlternatingItemStyle toe te voegen, zoals in het voorbeeld hieronder, waar de achtergrondkleur gewijzigd werd:
datalistalt.aspx (fragment)
In Visual Studio selecteer je hiervoor de DataList, en je wijzigt de property AlternatingItemStyle in het property-paneel.
Je hoeft hier dus geen AlternatingItemTemplate te maken, waar je (zoals bij de repeater hierboven) dezelfde code van het ItemTemplate grotendeels moet herhalen. Alleen de opmaak ("Style") wordt hier aangepast.
Het ene sluit echter het andere niet uit: je kan ze ook samen gebruiken.
Tip: het is nog beter als je de kleur kan instellen met behulp van een stylesheet. Maak bijvoorbeeld een stijlklasse "altstyle" met de juiste instellingen, en gebruik de CssClass-property:

### Meerdere kolommen gebruiken in een DataList-control

Door de property RepeatColumns van de DataList in te stellen op 2 i.p.v. 0 wordt de lijst gespreid over twee kolommen op je pagina.
Alleen de DataList-control heeft deze mogelijkheid.
Andere property's RepeatDirection en RepeatLayout geven je nog extra opties.

### Gegevens selecteren met een DataList-control

De DataList-control biedt de mogelijkheid om één item te selecteren uit de lijst. Dit item krijgt dan een eigen opmaak via de SelectedItemStyle. Bovendien kan je het SelectedItemTemplate gebruiken om van dit item bijvoorbeeld meer informatie te tonen dan van de andere.
datalistselect.aspx
Opmerkingen:
* Het ItemTemplate hierboven bevat alleen een label met de naam, het SelectedItemTemplate bevat ook de voornaam.
* Om een item te kunnen selecteren, werd een LinkButton toegevoegd aan het ItemTemplate.
Belangrijk is dat de property CommandName van deze LinkButton ingesteld werd op "Select". Hierdoor zal het klikken op deze LinkButton er automatisch voor zorgen dat de SelectedItemIndex van de DataList ingesteld wordt op het betreffende item.
* Alleen het instellen van de SelectedItemIndex is niet voldoende. De ganse DataList moet immers hertekend worden, en daarvoor moet de DataBind-methode aangeroepen worden. Dit doe je in het SelectedIndexChanged event van de DataList, dat je moet toevoegen.

#### Oefeningen

* Verander deze pagina zo dat je de naam en de voornaam altijd ziet, maar bij het klikken op "Selecteer" krijg je het ganse adres en het telefoonnummer erbij. Zorg er ook voor dat alle "Selecteer" links netjes onder mekaar staan.
* Zelfde oefening, maar voeg ook een alternerende kleur toe.
* Zelfde oefening, maar voeg nu twee knoppen toe ("vorige" en "volgende"), waarmee je het geselecteerde item instelt.

### Gegevens wijzigen met een DataList-control

Ook voor het wijzigen van gegevens heeft de DataList mogelijkheden ingebouwd. Hiervoor is er ook weer een aangepast template: het EditItemTemplate. Typisch zal je in dit template invoervakken (of aankruisvakjes of andere controls) voorzien, zodat de gebruiker de gegevens kan wijzigen.
datalistedit.aspx
Opmerkingen:
* In de plaats van de selecteerlink is er nu in het ItemTemplate een knop (het mocht evengoed weer een linkbutton zijn) voor het aanpassen van de gegevens. Deze knop krijgt de eigenschap CommandName="Edit".
* Bij het klikken op deze knop wordt het EditCommand-event van de DataList afgevuurd. Zorg voor een afhandeling van dit event (hierboven de DataList1_EditCommand handler). Je moet hierin 2 dingen doen:
** stel de EditItemIndex in van de DataList. Om te weten welke de index is gebruik je de eigenschappen van de DataListCommandEventArgs parameter e die met dit event meegegeven wordt: DataList1.EditItemIndex=e.Item.ItemIndex
** voer databinding uit om de DataList opnieuw op te bouwen.
* Bekijk het EditItemTemplate hierboven. Het label voor de naam uit het ItemTemplate is hier vervangen door een invoervak.
* Er is ook een knop voorzien om de wijzigingen door te voeren. Deze knop krijgt de eigenschap CommandName="Update".
* Bij het klikken op deze knop wordt het UpdateCommand event van de DataList afgevuurd. Zorg voor een afhandeling van dit event (hierboven de DataList1_UpdateCommand handler). Hierin moet je de nieuwe gegevens naar de databank sturen, en de DataList hertekenen.
* De nieuw ingevoerde naam krijg je via CType(e.Item.FindControl("tbNaam"), TextBox).Text. Aangezien elk item in de DataList een vak TextBox1 bevat, kan je niet gewoon tbNaam.Text gebruiken. Met de FindControl-methode kan je binnen een bepaalde control (in dit geval het DataListItem) zoeken naar een andere control met een bepaald ID. CType zet e.Item.FindControl("tbNaam") (een Control-object) om in een TextBox-object. Dit noemt men een cast. Zonder CType zou je de property Text niet kunnen opvragen, want het Control-object zelf heeft geen Text-property.
* Het ID van het gewijzigde item krijg je via DataList1.DataKeys(e.Item.ItemIndex)
* Opdat dit laatste zou werken, moet je de eigenschap DataKeyField van de DataList instellen op "ID".
* Tenslotte is er in het EditItemTemplate ook nog een knop "Annuleren". Deze knop heeft de eigenschap CommandName="Cancel", en bij het klikken erop wordt het CancelCommand afgevuurd. Hierin moet je DataList1.EditItemIndex instellen op –1, en vervolgens de DataList weer binden.

#### Oefening

* Maak een databank met een tabel met gegevens over computers (Naam, Merk, Processor, Geheugen, Hardeschijf). Maak een pagina om die tabel te wijzigen.

### Gegevens verwijderen met een DataList-control

Naast een "update"-knop kan je ook een "delete"-knop voorzien. Deze knop moet de instelling CommandName="Delete" hebben. Probeer dit zelf uit, en voorzie het gepaste event om het record te verwijderen.
Tip: het is meestal een goed idee om hiervoor bevestiging van de gebruiker te vragen. Anders worden soms gegevens per ongeluk gewist.

#### Oefeningen

* Maak een datalist waar je adressen kan wijzigen.
* Zelfde oefening, maar je kan ook adressen toevoegen.
* Zelfde oefening, maar je kan ook adressen verwijderen.

### OnItemDataBound

Stel dat je de aandacht van de gebruiker op bepaalde rijen in de lijst wil vestigen, bijvoorbeeld als een bedrag negatief is. De datacontrols (dus ook de repeater) hebben een event dat uitgevoerd wordt voor elk item in de lijst: het ItemDataBound-event.
Dit event treedt op net voor het item toegevoegd wordt aan de control. Je kan op dat moment nog wijzigingen aanbrengen als je dat wilt.
Het ItemDataBound-event krijgt als tweede parameter (e) een object van het type DataListItemEventArgs. Dit kan je gebruiken in je code om toegang te krijgen tot het item:
* e.Item is het DataListItem. Dit is de rij van de DataList waarop alles wat in het template staat geplaatst wordt. Dit is een control die alle eigenschappen van een cel in een html-tabel heeft, zoals achtergrondkleur, rand, enz...
* e.Item.ItemType is het type van het item. Hiermee kan je controleren of het een gewoon item is, een alternating item, een geselecteerd item, een edit item, een headeritem of een footeritem.
* e.Item.ItemIndex is de index van het item, te beginnen vanaf 0. Dit geldt alleen voor gewone items en alternating items.
* e.Item.DataItem is een object dat overeenkomt met de rij uit de databank waarmee het item overeenstemt.
* DataBinder.Eval(e.Item.DataItem,"naamveld") geeft de waarde van het opgegeven veld in de databank voor het item.
* Om toegang te krijgen tot een bepaalde control binnen een template, kan je e.Item.FindControl("IDControl") gebruiken. IDControl is daarin de ID van de control binnen het template.
In de pagina hieronder worden adressen in Brussel getoond met een rode achtergrond.
datalistdatabound.aspx (fragment)
Merk op dat er een test nodig is om te controleren over welk template het gaat. Alleen voor het ItemTemplate en AlternatingItemTemplate wordt de code uitgevoerd. Voor andere templates zou de code fouten geven (het HeaderTemplate heeft bijvoorbeeld geen DataItem), dus dat moet vermeden worden.

#### Oefeningen

* Je kan het ItemDataBound-event ook gebruiken om allerlei code uit te voeren voor alle items in de lijst. Maak een DataList "Computers". Sommige velden geven als resultaat True/False. Vervang dit door Ja/Neen.
* Hierboven werd opgemerkt dat je voor het verwijderen van gegevens best bevestiging vraagt. Dit kan het best door een stukje JavaScript-code toe te voegen aan het client-side onclick-event van de Delete-knop. Dit doe je met btnDelete.Attributes.Add("onclick","return confirm('Ben je zeker?');"). Omdat elk item zijn eigen btnDelete heeft, moet je deze code in OnItemDataBound zetten. Breid oefening 3 van de vorige reeks uit met deze beveiliging.
* Maak een DataList "cd's" met in het SelectedItemTemplate een Repeater-control. Deze repeater toont alle nummers van de betreffende cd. Gebruik het ItemDataBound event van de DataList om de repeater te vullen met gegevens. Zorg ervoor dat dit alleen gebeurt in het SelectedItemTemplate.
* Zelfde oefening, maar gebruik nu een DataList in plaats van een Repeater. Je krijgt dus een DataList binnen een DataList (geneste DataList).

### Eigen commando's maken

Je kan de CommandName-property van een knop binnen een DataList instellen op de reeds genoemde commando's: "Select", "Edit", "Update", "Delete" en "Cancel". Deze commando's hebben een voorgeprogrammeerde betekenis in ASP.NET.
Je kan ook zelf je eigen commando's toevoegen. Je kan bijvoorbeeld een knop toevoegen met commando's zoals CommandName="Controleren" of CommandName="Volgende".
De voorgeprogrammeerde commando's hebben elk hun eigen event-handler. Om je eigen commando's te verwerken gebruik je de algemene handler OnItemCommand. Je moet dan testen welk commando precies de handler veroorzaakt. Dit kan je achterhalen met behulp van e.CommandName (e is de tweede parameter van OnItemCommand).
Gebruik de volgende code:

#### Oefening

* Maak een DataList met adressen. Zorg ervoor dat het ItemTemplate leeg is, terwijl het SelectedItemTemplate wel gegevens toont. Begin met het eerste item geselecteerd, zodat je alleen het eerste adres op het scherm krijgt. Voeg nu een knop "Volgende" toe aan het SelectedItemTemplate. Als je op de knop klikt, krijg je het volgende adres uit de databank.

### Memo-velden en regeleindes

In sommige databankvelden kan tekst ingevoerd worden die regeleindes bevat (carriage returns). In Access bijvoorbeeld gebruik je daarvoor een Memo-veld.
Er ontstaat nu een probleem bij de weergave van deze velden in een html-pagina. Dit komt omdat de browser regeleindes beschouwt als open ruimte, en die worden gewoon weergegeven als een spatie.
In feite komt het erop neer dat je als ontwikkelaar bij de weergave van een memo-veld alle regeleindes moet omzetten in -tags.
Hiervoor gebruik je de volgende functie (een zogenaamde helper-functie):
In je datalist bijvoorbeeld roep je deze functie op de volgende manier aan:

## DataGrid

De derde veelgebruikte control is de DataGrid-control. Hiermee kan je gegevens vanaf een databank (maar ook vanaf andere bronnen) tonen in de vorm van een tabel. Een voordeel van de DataGrid-control is dat hij al gegevens kan tonen zonder één enkel template.
Deze control kan in ASP.NET 2.0 beter vervangen worden door een GridView-control, die veel krachtiger is. In Visual Studio 2005 vind je de DataGrid zelfs niet meer op de toolbox.
We bespreken de DataGrid hier kort voor pagina's die nog in ASP.NET 1.x gemaakt zijn. Dit is de code voor alleen het weergeven van de data in ASP.NET 1.x:

### Gegevens ophalen met een DataGrid-control

datagrid.aspx
Merk op dat je nergens namen van velden moet ingeven: de DataGrid maakt volledig automatisch een tabel aan!

### Gegevens wijzigen met een DataGrid-control

Om gegevens te kunnen wijzigen moet je de datasource control aanpassen, zodat die ook INSERT, UPDATE en DELETE-commando’s bevat. Dit doe je door in de wizard de knop “Advanced” te gebruiken.
Het wijzigen van gegevens is volledig vergelijkbaar met het wijzigen van gegevens in een DataList, behalve dat de DataGrid ook het EditItemTemplate zelf automatisch kan aanmaken.
In de UpdateCommand event handler moet je te weten komen welke de nieuwe gegevens zijn die de gebruiker ingevuld heeft.
Bij een DataList gebruikte je hiervoor e.Item.FindControl("idVanHetTekstvak"). Bij een DataGrid ken je de id's meestal niet (omdat alles automatisch aangemaakt wordt). Daarom gebruik je een andere methode:
waarbij k het nummer van de kolom is (te beginnen vanaf 0). Controls(0) is de eerste control binnen een cel, en dat is inderdaad het tekstvak in die kolom.