Avatar billede styrmand Nybegynder
24. september 2004 - 12:17 Der er 9 kommentarer og
2 løsninger

Dynamiske formularer

Formularer opbygges normalt ved at "klippe/klistre" <asp:... koder ind på en formular. Herved genereres formularkoden, med alle de fordele og ulemper det medfører.

Jeg vil gerne bygge formularerne dynamisk. Altså f.eks. lave en funktion, som skaber en bestemt formular.

Problemet er så vidt jeg kan se, at formularen dannes, før koden eksekveres. Er det forkert?

Er der nogen her, som har prøvet at danne en formular med kode?

Mvh

Ole
Avatar billede snepnet Nybegynder
24. september 2004 - 12:37 #1
ja det har jeg lavet en hel del af, og jeg vil meget gerne give en hånd.... men jeg kan ikke før i aften :o(

indtil videre kan du tage et kig på denne.... den kan relateres.
http://www.eksperten.dk/spm/519579

mvh
Avatar billede jakobandersen Nybegynder
24. september 2004 - 14:47 #2
Du kan genere en formular ret simpelt. Nedenstående eksempel tager f.eks. en Control som parameter(f.eks. en placeholder eller evt. Page) og tilføjer så en lille formular til siden.

Dog skal du være opmærksom på at eventhandler vil tabes ved næste postback(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconcontrolexecutionlifecycle.asp).

Kan du ikke forklare hvad du skal bruge det til, i mange tilfælde er der en bedre løsning.

void BuildSubscribeNewsLetterForm(Control parent){
    Label EmailLabel     = new Label();
    EmailLabel.Text        = "Email: ";
    TextBox Email        = new TextBox();
    Email.ID         = "Email";
   
    Label NavnLabel        = new Label();
    NavnLabel.Text        = "Navn: ";
    TextBox Navn        = new TextBox();
    Navn.ID            = "Navn";
   
    Button Subscribe    = new Button();
    Subscribe.Text        = "Tilmeld";
    Subscribe.Click        += new EventHandler(this.Subscribe_Click);
           
    Literal LineBreak    = new Literal();
    LineBreak.Text        = "<br />";

    parent.Controls.Add(EmailLabel);
    parent.Controls.Add(Email);
    parent.Controls.Add(LineBreak);
           
    parent.Controls.Add(NavnLabel);
    parent.Controls.Add(Navn);
    parent.Controls.Add(LineBreak);
           
    parent.Controls.Add(Subscribe);
}
Avatar billede styrmand Nybegynder
24. september 2004 - 15:51 #3
Hvad skal jeg bruge det til - lad mig nu se om jeg kan koge det ned...

I min "tidligere ASP og JSP tilværelse" har jeg altid haft et overordnet princip om at et website kun skal have én adresse/side. Jeg vil ikke sidde og arbejde med flere ASPx dokumenter og hermed flere designflader i HTML.
I stedet vil jeg generere sidens indhold dynamisk.

Hvis jeg f.eks. har mit HTML-dokument
<HTML>...<Body></body></html>

Vil jeg lade min kode bygge sidens indhold.
I gammel ASP kunne det f.eks. se sådan ud:
-----
HTML-dokumentet
-----
<HTML>...<Body><%Response.write Main(1)%></body></html>
-----

Main er så en funktion som returnerer det komplette sidedesign, altså f.eks.:


Funktionen (metoden) ser således ud:
--------------------
Function Main (sideID)
  Select case sideId
    case 1:  Main="<Table><tr><Td>Venstre kolonne</td><Td>Center</td><Td>Højre</td></tr></table>"
    case 2: ....
  End Select
end function
--------------------
Ovenstående viser en simpel side med 3 kolonner/én række, som hver indeholder en tekst.

Jeg anvender dog klasser, konstanter o.a., men ovenstående skulle være en simplificeret udgave af princippet. I virkeligheden er det hele dog langt mere kompleks.

Alt det kan jeg også gøre med asp.net.
Som du jo ved, er der kommet nogle interessante nye ting i forbindelse med håndteringen af formularer. Problemet er så, at det kan jeg ikke rigtigt få til at passe ind i modellen.
Hvad nu hvis jeg ville danne en formular i stedet for den simple tekst "Center"?
Alså noget som ender med at vises som:
<form>Navn..:<Input type="text" ... </form>

Jeg vil gerne danne formularer, der opfører sig som almindelige formularer, som var de lavet med <asp:... tags. og altså også events og klient/servervalideringer.

Jeg tror nok Snepnet er inde på det rigtige i det link han har givet, men jeg kan ikke teste det i min Visual Studio, Den kan ikke finde c#-compileren! VS er noget L... :-)

Er det noget rod? Kan du forstå, hvad jeg mener? Ellers må jeg jo prøve at forklare på en anden måde - det er lidt komplekst at beskrive.

Mvh

Ole
Avatar billede snepnet Nybegynder
24. september 2004 - 19:09 #4
hej ole :o)

der er rigtig mange (og gode) muligheder for at generere sine sider dymanisk.
jeg finder det lidt tvivlsomt om hvorvidt det er fordel for dig at benytte en fremgangsmåde med kun én form, men det er nok noget som du langt bedre selv kan vurdere efterhånden som du arbejder dig frem.

Du kan lige få et lille asp.net pendant (udelukkende baseret på serverkontroller) til det asp-eksempel du selv har givet :

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace EXP2
{
    public class Styrmand : System.Web.UI.Page
    {
        // objekt til generering af sidekontroller
        protected PageGenerator pageGenerator = new PageGenerator();

        // sidens serverform
        protected HtmlForm Form1;

        // entydig adgang til
        protected int PageId
        {
            get
            {
                try
                {
                    return (object)Request.QueryString["PageId"] != null ? int.Parse(Request.QueryString["PageId"]) : -1;
                }
                catch
                {
                    throw new Exception("PageId has not been set in querystring - please use ?PageId=<id>");
                }
            }
        }

        private void Page_Load(object sender, System.EventArgs e)
        {   
            // kalder bare metoden der generere kontroltræet til siden
            pageGenerator.AddPageControls(PageId, this.Form1);
        }

        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }
       
        private void InitializeComponent()
        {   
            this.Load += new System.EventHandler(this.Page_Load);
        }
    }

    // klasse der kan klaske kontroller ind på en form
    public class PageGenerator
    {
        private HtmlForm form;
        private int pageId;

        public void AddPageControls(int pageId, HtmlForm form)
        {
            this.form = form;
            this.pageId = pageId;

            switch(pageId)
            {
                case 0 :
                    AddPage0Controls();
                    break;
                case 1 :
                    AddPage1Controls();
                    break;
                default :
                    AddDefaultControls();
                    break;
            }
        }

        private void AddPage0Controls()
        {
            form.Controls.Add(new TextBox());
            form.Controls.Add(new Button());
        }

        private void AddPage1Controls()
        {
            form.Controls.Add(new Calendar());
            form.Controls.Add(new Button());
        }
        private void AddDefaultControls()
        {
            form.Controls.Add(new LiteralControl(String.Format("No controls defined for page{0}.", this.pageId)));
        }
    }
}

Ovenstående skal ikke umiddelbart ses som en anbefaling, men bare en objektorienteret-serverkontrolbaseret-eksempelagtig-omskrivning :o)

mvh
Avatar billede snepnet Nybegynder
24. september 2004 - 19:20 #5
Du kan lige se et andet eksempel her... Det laver en template baseret på UserControls om du vil (en slags minimum-masterpage... et koncept som er understøttet direkte i den nye betaversion).
http://www.eksperten.dk/spm/530150
Avatar billede snepnet Nybegynder
24. september 2004 - 19:23 #6
Det eksempel jeg linkede er desuden bygget op over at du laver en (eller flere) baseforms... Altså klasser baseret på Page-klassen.
Du sørger så for, at lave speciealiseringer af en given baseform, for at få indsat givne standardkontroller.

Du må endelig sige til, hvis du ønsker flere eksempler mv.

mvh
Avatar billede styrmand Nybegynder
25. september 2004 - 01:53 #7
Nå,- jeg har først fået set på koden her til aften. Jeg måtte geninstallere Visual Studio #¤%& . Den kunne ikke tåle at webmatrix (2eren), var installeret i forvejen. Og det tager bare en marsrejse at installere VS.

Men koden fungerer fint så tak for den.
Der er dog stadig et problem. Hvis man bruger Validation Controls vil de vel danne et script på klientsiden, men servervalideringen vil jo mangle, når svaret returneres, så man skal vel danne en side med de samme valideringkontroller igen for at kunn modtage og validere svaret?

Forms forventer vel at de ligger statisk, så den side der danner/viser formularen også er den side, som modtager svaret?


Til dit spørgsmål om formålet med at arbejde på den måde, er jeg såmænd heller ikke sikker på, at det er det rigtige at gøre. Jeg vil dog gerne lave en lagopdelt kode, hvor det øverste lag, kun skal arbejde med klientkode og styre de data/informationer som skal vises på siden.
På den måde kan den grafiske designers arbejde isoleres 100% og min kode arbejde  uafhængigt af ham.
Det kan også fint lade sig gøre, men formularerne er et problem, hvis jeg vel og mærke skal udnytte de nye valideringsmuligheder i ASP.NET. Jeg ved fra ASP, hvor irriterende det er at sidde og danne valideringer på såvel klientside som serverside - derfor vil jeg MEGET gerne bruge de nye faciliteter.
Der er tilsyneladende også nogle andre fordele ved de indbyggede formkontroller. I de små eksempler jeg selv har lavet, ser det ud til at sidernes design er meget ensartede, uanset om de vises på Mozilla eller i IE. Jeg glæder mig til ogs¨at prøve Opera. :-) Hvis det er det samme der, VIL jeg bare bruge de kontroller.

OnePageDesign:
Når en applikation vokser i omfang, opstår der efterhånden et utal af ASP(x)-sider. Det er noget af det værste ved Microsofts indgangsvinkel til serverprogrammeringen. For mig og se er der et paradox i, at man danner et fremragende objektorienteret sprogværktøj og så lader det udfolde sig på den kaotiske facon.
Programmøren kan skabe den mest vedligeholdelsesvenlige kode, men der er fuldstændig kaos i klientsiden. Den eneste fordel man får ud af det nye koncept er, at det er blevet nemmere at lave formularer - men en forbedring af struktur i forhold til gammel ASP, har de altså ikke formået at skabe i selve klientlaget. Det er nøjagtigt lige så kaotisk som det altid har været og følgen er et utal af selvstændige ASPx dokumenter, som arbejder selvstændigt.
Som jeg har forstået det, så kan man heller ikke have mere end en formular på hver ASPx side? Det er for mig at se også en besynderlig og uheldig begrænsning.

OnePageDesign giver desuden nogle fordele når siden skal forandres gennemgribende. Hvis et site eksempelvis skal "internationaliseres" er det et h...... at ændre sprog på måske 50-100 sider. Styres tekst og sprog i koden, har man helt andre muligheder. Så skal designeren kun involveres, hvis der er grafik, som indeholder tekst.

Nå, det var bare et svar på det og jeg er ikke skråsikker på, at der ikke skulle findes en smartere måde, som ligger lige for i ASP.Net - måske i de selvskabte kontroller...

Hvis du lige vil kaste et svar, gerne med kommentarer til det jeg skriver, hvis du har sådan nogen, så skal du få pointene. Dit eksempel var præcis det jeg ledte efter.

Mvh

Ole
Avatar billede snepnet Nybegynder
25. september 2004 - 03:34 #8
Et svar skal du få :o)

Og nogle kommentarer.

Med hensyn til valideringskontrollerne (og dynamisk opbyggede sider generelt), så har du helt ret i, at siden skal genopbygges ved et request.
(der findes dog tredjepartskontroller der kan sørge for at dynamisk indsatte kontroller "bliver hængende" i kontrolhierarkiet).

Jeg synes ikke der er noget der dikterer en kaotisk facon i ASP.NET, at implementere en customhttphandler (hvis du helt vil undgå aspx-sider) er meget ukompliceret, og de på det nærmeste ubegrænsede muligheder for opbygning af sider vha. af egne producerede user- og customcontrols kan give dig et meget rent snit i din applikation, og der er også god indbygget understøttelse for localization.

Jeg tror måske vi mener noget lidt forskelligt med klientdelen.... hvis du udelukkende bruger de indbyggede serverkontroller, ser du aldrig klientdelen i koden, men jeg tænker at du nok mener selve kontruktionen af din frontend.

Du kan have alle de forms du vil på en side, men det er helt korrekt at du kun kan have én serverside form.

Du har jo også en ny mulighed grundet objektmodellen der skabes på serveren... Du kan definere dig diverse baseforms, der varetager diverse funktionalitet og så basere dine egne forms på dem.

I den/dem kunne du så lægge diverse ting og sager som :
brugervalidering,
indsætning af header og footer,
navigationsspor,
standard dbio,
og meget meget mere.

du kan lige få et eksempel på en meget simpel customcontrol :

public class SimpleControl : Control
{
  protected override void CreateChildControls()
  {
      this.Controls.Add(new TextBox());
      this.Controls.Add(new Button());
  }
}

En kontrol som ovenstående kan indsættes programmatisk på en side ved :

someControlContainer.Controls.Add(new SimpleControl());

Og ControlContainer er der mange af... Selve dit page-objekt er selvfølgelig en container, og den serverform der oprettes som standard (hvis du arbejder med VS), er også en container.
Derudover er der på toppen f.eks. Panel og Placeholder, og de mere "indflettede" som f.eks. en TableCell.

Alle kontroller du selv laver baseret på en Control eller WebControl - eller specialisering af de allerede nævnte fungerer også som containers.

Såhh... et system som dette :

// baseform
public class FooterPage : Page
{
  protected override void OnPreRender(EventArgs e)
  {
      Controls.Add(new Footer());
      base.OnPreRender (e);
  }
}

// footercontrol baseret på et Panel
public class Footer : Panel
{
  protected override void OnInit(EventArgs e)
  {
      this.CssClass = "someClass";
      this.Controls.Add(new LiteralControl("FOOTER"));
      base.OnInit(e);
  }
}

Vil give dig muligheden for at basere alle dine forms på en FooterPage, og dermed sikre at de alle sætter en footer ind, og fremvises iht. en css-class du så har griflet ned i et stylesheet et sted.

På den måde kan du i høj grad opbygge dine sider på basefunktionalitet, og i de specifikke forsm der skal udgøre sitet, vil der så udelukkende eksistere kode der er helt specifik for den enkelte.

Nå... jeg sidder bare og ævler løs.... Du må endelig sige til hvis der bliver noget efterhånden som du griber fat i det.
Jeg vil meget gerne hjælpe med den slags.

mvh
Avatar billede snepnet Nybegynder
25. september 2004 - 04:07 #9
Et svar skal du få :o)

Og nogle kommentarer.

Med hensyn til valideringskontrollerne (og dynamisk opbyggede sider generelt), så har du helt ret i, at siden skal genopbygges på serveren ved hvert request.
(der findes dog tredjepartskontroller der kan sørge for at dynamisk indsatte kontroller "bliver hængende" i kontrolhierarkiet).

Jeg synes ikke der er noget der dikterer en kaotisk facon i ASP.NET. At implementere en customhttphandler (hvis du helt vil undgå aspx-sider) er meget ukompliceret, og de på det nærmeste ubegrænsede muligheder for opbygning af sider vha. af egne producerede user- og customcontrols kan giver rigtig gode muligheder for at strukturere din applikation, og der er også god indbygget understøttelse for localization.

Jeg tror måske vi mener noget lidt forskelligt med klientdelen.... hvis du udelukkende bruger de indbyggede serverkontroller, ser du aldrig klientdelen i koden, men jeg tænker at du nok mener selve kontruktionen af din frontend - eller ?

Du kan have alle de forms du vil på en side, men det er helt korrekt at du kun kan have én serverside form.
(Jeg har selv lidt svært ved at se behovet for flere serverside-forms, og hvis du har et bud vil jeg meget gerne høre det).

Du har jo også en ny mulighed grundet objektmodellen der skabes (og arbejdes i) på serveren... Du kan definere dig diverse baseforms, der varetager diverse funktionalitet, og så basere dine egne forms på dem.

I den/dem kunne du så lægge funktionalitet som :
brugerhåndtering,
indsætning af header og footer,
navigationsspor,
standard dbio,
localizationhåndtering,
og meget meget mere.

du kan lige se det her eksempel på en meget simpel customcontrol :

public class SimpleControl : Control
{
  protected override void CreateChildControls()
  {
      this.Controls.Add(new TextBox());
      this.Controls.Add(new Button());
  }
}

En kontrol som ovenstående kan indsættes programmatisk på en side ved :

someControlContainer.Controls.Add(new SimpleControl());

Og ControlContainer er der mange af... Selve dit page-objekt er selvfølgelig en container, og den serverform der oprettes som standard (hvis du arbejder med VS), er også en container.
Faktisk er alle kontroller som udgangspunkt containers, da de er baseret på Control, men det er visse af dem som du ikke for lov til at tilføje kontroller til (som f.eks. En tekstbox).

Alle kontroller du selv laver, baseret på en Control eller WebControl - eller andre allerede eksisterende - vil også fungere som containers.

Såhh... et system som dette :

// baseform
public class FooterPage : Page
{
  protected override void OnPreRender(EventArgs e)
  {
      Controls.Add(new Footer());
      base.OnPreRender (e);
  }
}

// footercontrol baseret på et Panel
public class Footer : Panel
{
  protected override void OnInit(EventArgs e)
  {
      this.CssClass = "someClass";
      this.Controls.Add(new LiteralControl("FOOTER"));
      base.OnInit(e);
  }
}

Vil give dig muligheden for at basere alle dine forms på en FooterPage, og dermed sikre at de alle sætter en footer ind, og fremvises iht. en css-class du så har griflet ned i et stylesheet et sted.

På den måde kan du i høj grad opbygge dine sider på basefunktionalitet, og i de specifikke forms der skal udgøre sitet, vil der så udelukkende eksistere kode der er helt specifik for den enkelte.

Nå... jeg sidder bare og ævler løs (og er ved at falde i søvn over tasterne).... Du må endelig sige til hvis der bliver noget efterhånden som du griber fat i det.
Jeg vil meget gerne hjælpe med den slags.

mvh
Avatar billede styrmand Nybegynder
25. september 2004 - 12:28 #10
Hej igen, jeg er meget glad for dine eksempler. PÅ mange måder beskriver de bedre end 300 sider fra amerikanske bøger, hvad tingene handler om. :-)
Jeg har nogle kapitler kliggende omkring custom-controls, som jeg skal i gang med. Men nu ved så allerede, hvad det omhandler i praksis.

Tak for det og vi snakkes helt sikkert ved herinde. :-)

Mvh

Ole
Avatar billede snepnet Nybegynder
25. september 2004 - 12:56 #11
Det var alletiders !

Jeg kan se at min meddelelse er kommet ind to gange... Det er meget overraskende :o)
jeg postede den på første gang lidt over halv fire, men fik en meddelelse om at eksperten var lukket for vedligehold, så jeg overvejede overhovedet ikke at den skulle være kommet ind alligevel, og postede den bare hjernedødt da klokken paserede 4 :o)

Nå - det går jo nok :o)

Jeg håber du får lavet nogle fede skeletter for dynamisk sidegenerering, og at du poster nogle fede spørgsmål omkring det herude :o)

Vi ses
mvh
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester