Nyeste it-job

Lektion 13: Brugerkontroller - fortsat

Af Michell Cronberg

I forrige lektion kiggede vi på udvikling og brug af en simpel brugerkontrol. I denne artikel ser vi på en lidt mere avanceret brug af brugerkontroller.

OOP

I objektorienteret programmering (OOP) er det normalt at oprette klasser som indeholder både egenskaber og metoder. Egenskaberne kan betragtes som en mulighed for at tilgå klassens interne data, således at man kan styre både tildeling og aflæsning. Metoderne derimod er klassens funktionalitet.

Da en brugerkontrol kan opfattes som en klasse, åbner det mulighed for at opbygge meget effektive kontroller. I denne serie er der ikke plads til en nærmere gennemgang af de objektorienterede principper, men lad os se på et simpelt eksempel.

Eksempel

Lad os antage at vi skal skabe en kontrol som skal bruges til at indsamle oplysninger gennem en formular. Der skal indsamles en dato (fra en tekstboks) og et heltal (fra en tekstboks). Kontrollen skal "validere sig selv" således at der ikke kan aflæses forkerte værdier, og skal kunne initialiseres på en nem måde.

Lad os starte med en del af kontrollen:

<table>
  <tr>
    <td>Tekstboks til dato</td>
    <td>
      <asp:textbox id=txtdato runat=server />
    </td>
    <td>
      <asp:CompareValidator runat="server" 
      ErrorMessage="Fejl i dato" Type="Date" 
      Operator="DataTypeCheck" Display="Dynamic" 
      ControlToValidate="txtdato" />
    </td>
  </tr>
  <tr>
    <td>Tekstboks til heltal</td>
    <td>
      <asp:textbox id=txtheltal runat=server />
     </td>
    <td>
      <asp:CompareValidator runat="server" 
      ErrorMessage="Fejl i heltal" Type="Integer" 
      Operator="DataTypeCheck" Display="Dynamic" 
      ControlToValidate="txtheltal" />
    </td>
  </tr>
</table>

Her skabes en tabel med to tekstbokse. I den ene (txtdato) skal der indtastes en korrekt dato hvilket er sikret med en valideringskontrol. I den anden (txtheltal) skal der indtastes et korrekt heltal, hvilket en valideringskontrol også garanterer.

Hvis koden gemmes som en brugerkontrol, kan den som tidligere nævnt benyttes på andre sider til at indhente data fra brugeren. Der er dog et problem, idet man som udgangspunkt ikke udefra kan komme til de to tekstbokse for at aflæse værdier. Det skyldes, at tekstboksene er indkapslet i selve kontrollen, og vi er nødt til at skrive lidt kode for at kunne tilgå værdierne.

Egenskaber

Det kan gøres på flere måder, men i objektorienteret sammenhæng er det mest korrekte at kode et par egenskaber (properties). De giver samtidig mulighed for at kunne tildele og aflæse værdier i den korrekte datatype.

Følgende kode kan tilføjes kontrollen:

Visual Basic .NET

<%@ Control Language="VB" %>

<script runat=server> 
    Public Property Dato() As DateTime
    Get
      If txtDato.Text = "" Then
        txtDato.Text = DateTime.Now.ToString("dd-MM-yyyy")
      End If
      Return Convert.ToDateTime(txtDato.Text)
    End Get
    Set(ByVal Value As DateTime)
      txtDato.Text = Value.ToString("dd-MM-yyyy")
    End Set
  End Property

  Public Property Heltal() As Integer
    Get
      If txtHeltal.Text = "" Then
        txtHeltal.Text = "0"
      End If
      Return Convert.ToInt32(txtHeltal.Text)
    End Get
    Set(ByVal Value As Integer)
      txtHeltal.Text = Value.ToString
    End Set
  End Property  
</script>

C#

<%@ Control Language="C#" %>

<script runat=server> 

    public DateTime Dato
    {
      get{
        if(txtdato.Text=="")
          txtdato.Text = DateTime.Now.ToString("dd-MM-yyyy");
        return Convert.ToDateTime(txtdato.Text);
      }
      set{
        txtdato.Text = value.ToString("dd-MM-yyyy");
      }
    }

    public int Heltal
    {
      get{
        if(txtheltal.Text=="")
          txtheltal.Text = "0";
        return Convert.ToInt32(txtheltal.Text);
      }
      set{
        txtheltal.Text = value.ToString();
      }
    }

</script>

Der skabes to egenskaber kaldet henholdsvis Dato af datatypen DateTime og Heltal af datatypen Int32. Når der tildeles værdier til egenskaben (SET-delen), formateres værdierne automatisk og indsættes i de respektive tekstbokse. På den måde sikrer man at der ikke kan tildeles en forkert værdi (man kan eksempelvis ikke tildele Dato-tekstboksen en værdi som ikke er en DateTime), og at der altid benyttes den samme formatering. Ved aflæsning (GET-delen) returneres indholdet af tekstboksen i det korrekte dataformat, og i dette eksempel sikres det samtidig at der altid kan aflæses en værdi. Efterlader brugeren Dato-tekstboksen tom, returneres systemdatoen, og ved en tom Heltal-tekstboks returneres værdien nul.

Nu kan man både aflæse og tildele en værdi udefra, og man behøver ikke tænke på hvordan en tildeling skal formateres, eller selv foretage en datakonvertering. Yderligere behøver man ikke i dette eksempel tænke på hvilke default-værdier der benyttes hvis brugeren efterlader en tekstboks tom. Alt dette klarer kontrollen helt på egen hånd.

Her er kontrollen i funktion:

Visual Basic .NET

<%@ Page Language="VB" %>
<%@ Register TagPrefix="aspnetdemo" TagName="inputkontrol" 
Src="inputkontrol.ascx" %>

<script runat=server>

 Private Sub Page_Load(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) 
    ' Initialisering af data
    If Not Page.IsPostBack Then
      MinKontrol.Dato = DateTime.Now
      MinKontrol.Heltal = 0
    End If
  End Sub

  Private Sub cmbsubmit_click(ByVal sender As System.Object, _
  ByVal e As System.EventArgs)

    ' Aflæsning af data fra kontrol (bemærk, at data kan aflæses
    ' som korrekte datatyper)
    lblDato.Text = "Dato = " & MinKontrol.Dato.ToString("D")
    lblHeltal.Text = "Heltal = " & MinKontrol.Heltal.ToString()

  End Sub
  
</script>

<html><body>
  <form runat="server">           
    <aspnetdemo:inputkontrol id="minkontrol" runat="server" />
    
    <asp:button text="Submit" id=cmbsubmit 
    onclick="cmbsubmit_click" runat=server />
    
    <hr>
    <asp:label runat=server id=lbldato /><br/>
    <asp:label runat=server id=lblheltal />
  </form>
</body>
</html>

C#

<%@ Page Language="C#" %>
<%@ Register TagPrefix="aspnetdemo" TagName="inputkontrol" 
Src="inputkontrol.ascx" %>

<script runat=server>

  private void Page_Load(object sender, System.EventArgs e)
  {
    // Initialisering af data
    if(!Page.IsPostBack)
    {
      minkontrol.Dato = DateTime.Now;
      minkontrol.Heltal = (int)0;
    }
  }

  private void cmbsubmit_click(object sender, System.EventArgs e)
  {
    //Aflæsning af data fra kontrol (bemærk, at data kan aflæses
    //som korrekte datatyper)
    lbldato.Text = "Dato = " + minkontrol.Dato.ToString("D");
    lblheltal.Text = "Heltal = " + minkontrol.Heltal.ToString();
  }
        
</script>

<html><body>
  <form runat="server">           
    <aspnetdemo:inputkontrol id="minkontrol" runat="server" />
    
    <asp:button text="Submit" id=cmbsubmit 
    onclick="cmbsubmit_click" runat=server />
    
    <hr>
    <asp:label runat=server id=lbldato /><br/>
    <asp:label runat=server id=lblheltal />
  </form>
</body>
</html>

Koden resulterer i følgende:

Brug af kontrollen

Figur 1: Brug af kontrollen

Når siden loades første gang, tildeles de to tekstbokse en værdi i Page_Load(). Bemærk at der tildeles værdier i de korrekte datatyper - hvis der var brugt "almindelige" tekstbokse, skulle man selv konvertere til tekst inden der kunne tildeles værdier.

Når der trykkes på Submit-knappen, aflæses værdierne, og igen returnerer kontrollen de korrekte datatyper:

Kontrollen giver tilgang til tekstboksene gennem egenskaber

Figur 2: Kontrollen giver tilgang til tekstboksene gennem egenskaber

Slutteligt sørger kontrollen selv for at returnere default-værdier hvis brugeren ikke har indtastet noget.

Mere avanceret brug

Koden er et relativt simpelt eksempel på brug af en af de stærke sider ved objektorienteret programmering (OOP) - nemlig brug af egenskaber.

Samme funktionalitet bliver også brugt i mere avancerede situationer hvor gevinsten ved brug af OOP er mere synlig. Eksempelvis er der store fordele ved at pakke en liste (eksempelvis en Listbox) ind i en egenskab. Når der tildeles en værdi, kan egenskaben selv sørge for at finde og markere et element, og når der aflæses, returneres automatisk værdien af det valgte element. Det samme gør sig gældende for en Checkbox-kontrol, idet der her kan benyttes en sand/falsk egenskab (Boolean) til at kontrollere om kontrollen er markeret.

I nogle situationer kan det også være praktisk at aflæse andet end værdier fra enkelte kontroller - eksempelvis kan der skabes en readonly-egenskab der returnerer et SQL-kald til opdatering af data i en database eller en XML-struktur bestående af værdier fra samtlige kontroller i en brugerkontrol.

Fælles for alle eksemplerne er at brugen af egenskaber indkapsler en funktionalitet i selve brugerkontrollen og gør brugerkontrollen nem at benytte på en ASP.NET-side - både hvad angår tildeling og aflæsning.


Nyhedsbrev
Tilmeld dig HTML.dk's nyhedsbrev


Er du jobsøgende?

 Ja
 Nej
Se det foreløbige resultat når du har stemt!


Se tidligere afstemninger

 Community
Brugernavn

Adgangskode

Husk

 *  Bliv medlem her
 *  Glemt password?


Om HTML.dk | Oplysninger om ophavsret | Politik om persondata | Annoncer på HTML.dk | RSS

Valid XHTML 1.1! Valid CSS! Powered by Scannet