Avatar billede pede15 Nybegynder
12. juli 2005 - 10:55 Der er 39 kommentarer og
1 løsning

Forhindre brugeren i at gå tilbage i quiz app

Jeg er ved at lave en app hvor brugeren skal svare på nogle spørgsmål, 1 ad gangen - altså en slags quiz. Er det muligt at forhindre brugeren i at gå tilbage? Jeg tænker ikke på fikse løsninger med javscript eller lignende - men altså server-side forhindre at brugeren kan gå tilbage og svare på forrige spørgsmål hvis han eller hun svarede forkert.

Med venlig hilsen
Peder

PS: jeg vil MEGET gerne høre forslag - er blank og skal gerne ha det løst :)
Avatar billede arne_v Ekspert
12. juli 2005 - 10:58 #1
du kan da sagtens gemme oplysninger om hvad der er besvaret både
permanent (database) og temporært (session) og checke for det

det forudsætter kun en host interaktion per besvarelse
Avatar billede dr_chaos Nybegynder
12. juli 2005 - 10:59 #2
hvis du gemme data i en database kan du når brugeren vil submitte et svar se om brugeren har svaret på spørgsmålet før og hvis det er tilfældet så smider du ikke noget data i databasen ellers gør du.
Avatar billede pede15 Nybegynder
12. juli 2005 - 11:34 #3
skal lige prøve noget.
Avatar billede snepnet Nybegynder
12. juli 2005 - 11:37 #4
du kunne gøre det, at du opretter dig en liste af spørgsmål i session når brugeren starter op :
(bare sådan lidt pseudokodeagtigt)

public enum QuestionState
{
  ...
  .
  New,
  Answered,
  .
  ...
}

public class Question
{
  ...
  .
  int questionId;
  string question;
  QuestionState state;
  int step;
  .
  ...
}

public class QuestionCollection
{
  ...
  .
  Question[] GetQuestions(int step)
  {
    // kunne så returnere spm's for et givent step
  }
  .
  ...
}

når brugeren så går ind til en spørgerunde kan du lave noget

Session["Questions"] = BLL.GetQuestions(...);

og du kunne sørge for at lave en baseform for de sider der indgår i spørgerunden... den kunne så f.eks. have en property der referer en spørgsmålssamling i session

protected Questions
{
  get{return Session["Questions"];}
  set{Session["Questions"] = value;}
}

og på hver side:

foreach(Question question in Questions.GetQuestions(someStep))
{
  if(!question.State == QuestionState.Answered)
  {
    // ... giv mulighed for at besvare det.
  }
}

så kan du så ... når brugeren trykker "besvar" på den enkelte side - opdatere de aktuelle spørgsmål :

foreach(Question question ...
question.State = QuestionState.Answered;

... det nemmeste er nok, hvis du laver dig en lille kontrol som selv finder ud af hvordan spørgsmålet skal renderes iht spørgsmålets tilstand.

mvh
Avatar billede pede15 Nybegynder
12. juli 2005 - 11:56 #5
Jeg prøver "lige" at implementere dit forslag snepnet - og tak! :D
Avatar billede snepnet Nybegynder
12. juli 2005 - 12:15 #6
du siger bare til hvis der er noget :o)
mvh
Avatar billede snepnet Nybegynder
12. juli 2005 - 12:34 #7
æhh... denne :

protected Questions
{
  .. get/set ..
}

skulle self. have set sådan her ud :o)

protected QuestionCollections Questions
{
  .. get/set ..
}

du kan jo også bare bruge en arraylist - det kan da spare lidt kodelinier med mindre du bruger V2.0

og en anden ting .... du skal nok under alle omstændigheder sørge for at persistere besvarelserne i basen mellem hvert step - ellers kan man jo sådan set lukke browseren og vente til sessionen er timet ud, og så besvare igen :o)

mvh
Avatar billede pede15 Nybegynder
12. juli 2005 - 13:55 #8
puha.. det er ikke helt let det her :) - det sq også lidt over det niveau (mht. programmering) jeg plejer at lægge for dagen! Så, ved du det snepnet - såfremt du sidder og tænker 'what's taking him so long?' Hvis ikke det var for 'JEG VIL SELV!' ville der være en lind strøm af spørgsmål :) kan dog godt være der kommer et om lidt.. Oo
Avatar billede snepnet Nybegynder
12. juli 2005 - 14:03 #9
hehe ... det tænker jeg overhovedet ikke.
bare gå til vaflerne - og spørg løs her hvis der er noget du gerne vil have svar på her :o)
mvh
Avatar billede pede15 Nybegynder
12. juli 2005 - 14:20 #10
herligt! :D - ok, here we go:

jeg en class Question, som repræsenterer 1 spørgsmål. Nu vil jeg så til at lave QuestionsCollection, og jeg har den ide at den skal nedarve System.Collections.ArrayList (dum ide?) - anyway.. så skal den jo have en public method Add(Question q) - hvilket jeg så har gjort på følgende måde:
public class QuestionsCollection : System.Collections.ArrayList
{
  ......
  public void Add(Question q)
  {
      base.Add(q);
  }
  .....
}

- er det korrekt? (det er første gang jeg laver sådan noget her :) )
Avatar billede arne_v Ekspert
12. juli 2005 - 14:22 #11
man plejer ofte at arve fra CollectionBase
Avatar billede pede15 Nybegynder
12. juli 2005 - 14:23 #12
.....(det er tilladt at grine)..... ooooh, er der sådan en? :D (lol.. for helv.. )
Avatar billede arne_v Ekspert
12. juli 2005 - 14:30 #13
kig evt. i http://www.eksperten.dk/artikler/694 afsnittet "Generics"
Avatar billede pede15 Nybegynder
12. juli 2005 - 14:36 #14
Oh, ja.. 2.0 - gid det var det jeg sad med :(
Avatar billede pede15 Nybegynder
12. juli 2005 - 14:40 #15
jeg forstår ikke helt den her:

public int Add(MyData value)   
{   
    return List.Add(value);
}

- return type er int ? jeg troede det skulle være void
Avatar billede pede15 Nybegynder
12. juli 2005 - 14:42 #16
Måske skulle jeg liiige tage og kigge i dokumentationen inden jeg kaster spørgsmål herind.

"Return Value: The position into which the new element was inserted"
Avatar billede snepnet Nybegynder
12. juli 2005 - 15:57 #17
hej - undskyld men jeg var nødt til at forlade maskinen i en periode :o(
men det går fremad kan jeg se - cool.
men ellers ja - du kan godt "bare" nøjes med en liste baseret på en arraylist, men det er at foretrække med en typestærk collection i mange tilfælde (som dit ;o).
har du fået lavet en - eller er der stadig nogle huller?
mvh
(og... er det helt udelukket at du kan bruge V2.0?)
Avatar billede pede15 Nybegynder
12. juli 2005 - 16:44 #18
2.0 er udelukket da jeg sådan set er ved at lave den resterende del af et helt system ... desværre :/

Således ser min QuestionCollection ud:

public class QuestionsCollection : System.Collections.CollectionBase
{
    #region Constructors
   
    public QuestionsCollection()
    {}
   
    #endregion

    #region Private properties
    #endregion

    #region Public properties
   
    public Question this[int index]
    {
        get{ return (Question)List[index]; }
    }

    public int Count
    {
        get{ return List.Count;}
    }
   
    #endregion

    #region Private methods
    #endregion

    #region Public methods
   
    public int Add(Question q)
    {
        return List.Add(q);
    }
   
    #endregion

}

- er den ikke flot? (min første collection :) )

Er ved at lave en base-class til siderne som skal vise spørgsmålene, og diverse andre ting - men nu var det der med collection den første hurdle.. indtil videre går det fremad... en smule langsomt.. men det her er så også det mest avancerede jeg har lavet endnu! (hvem grinte?!)
Avatar billede snepnet Nybegynder
12. juli 2005 - 16:54 #19
ingen griner .... der er mange der aldrig kommer til det (altså f.eks. at lave sin egen typestærke collection mv).

giver compileren dig ikke en warning på

    public int Count
    {
        get{ return List.Count;}
    }

den skulle være implementeret på CollectionBase

mvh
Avatar billede pede15 Nybegynder
12. juli 2005 - 16:54 #20
eller ah.. ok.. nok ikke det mest avancerede.. var bare svært i starten... men når man så lige har fået den der Ah-haaah oplevelse så er jo egentlig forholdsvis simpelt.
Avatar billede pede15 Nybegynder
12. juli 2005 - 16:56 #21
nej, får ingen warnings eller errors mht. Count - men nåja.. der er jo ingen grund til at have den når den nedarves fra CollectionBase ( FOR dælen jeg lærer meget idag! :D )
Avatar billede snepnet Nybegynder
12. juli 2005 - 16:56 #22
hehe - det kan jo gå hen og blive en rigtig god dag ;o)
mvh
Avatar billede pede15 Nybegynder
12. juli 2005 - 17:05 #23
Det er ihvertfald godt på vej! - sidder ligenu og prøver at finde ud af hvilke classes jeg ellers skal ha lavet.. skal nok have lavet en "parser" af en art.. ..og nok også en som kan finde ud af hvilken type WebControl den skal sætte ind til det pågældende spørgsmål... puha.. det sortner allerede for mine øjne.
Avatar billede snepnet Nybegynder
12. juli 2005 - 17:50 #24
:o)

det skal nok gå ... du kan jo lave helt din egen hvis du skulle have lyst til at prøve den slags også ;o)

du kan relativt enkelt lave en webcontrol du kan bruge programmatisk :
(igen bare lidt pseudo-agtigt)

public class QuestionControl : WebControl, INamingContainer
{
  private Question question;
  private Label lblQuestion;
  private TextBox txtAnswer;

  public QuestionControl(Question question)
  {
    this.question = question;
  }

  protected override void CreateChildControls()
  {
    lblQuestion = new Label();
    lblQuestion.Text = question.QuestionText;
    Controls.Add(lblQuestion);

    txtAnswer = new TextBox();
    if(question.State == QuestionState.Answered)
      txtAnswer.Enabled = false;
    Controls.Add(txtAnswer);
   
    ChildControlsCreated = true;
  }
}

men men men ... der skal lidt mere til før det hele går op i en højere enhed ;o)

mvh
Avatar billede pede15 Nybegynder
12. juli 2005 - 18:30 #25
nu er det således at det er forskelligt hvordan der skal svares. I nogle spørgsmål skal man vælge en ting i en dropdownlist, andre spørgsmål skal der skrives i en textbox ... mit spørgsmål er om det ikke ville være en fordel at lave min egen QuestionControl når scenariet er som det er?  - fx at constructoren tager et Question som parameter og så ud fra en property på Question, finder ud af at lave de rette controls.

mvh
Peder ( og mange tak for dit engagement - det er yderst værdsat!)
Avatar billede snepnet Nybegynder
12. juli 2005 - 19:03 #26
selv tak :o)

prøv at kast et kig på den her http://www.eksperten.dk/spm/519579
den er sådan lidt i samme skuffe...

du kan lige skrive når du har kigget den igennem.

jeg ville selv gøre som du skriver, men der er mange løsninger på den slags... du kan sådan set også bare bruge en repeater - og så opbygge den for hver række i databoundeventet - men det bliver meget hurtigt noget værre gnidder.

men det kunne blive lidt som sådan noget her:

private void OuterRepeater_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
  if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
  {
    // du kunne have et panel i din repeater - til at sætte spørgsmålet op i
    Panel questionPanel = e.Item.FindControl("pnlQuestionPanel") as Panel;
    Question question = e.Item.DataItem as Question;
    if(q.QuestionType == QuestionType.Blah)
    {
      Label lblQuestion = new Label();
      lblQuestion.Text = question.QuestionText;
      questionPanel.Controls.Add(lblQuestion);

      TextBox txtAnswer = new TextBox();
      questionPanel.Controls.Add(txtAnswer);   
    }
  }
}

det kan self. gøres fiksere - men det bliver for det meste lidt noget rod alligevel.

mvh
Avatar billede pede15 Nybegynder
13. juli 2005 - 08:45 #27
Jeg har kigget på linket der, og kan godt se at det er noget lignende det jeg er ved at lave. Men jeg vil så gerne lave noget der er ordentligt struktureret - ihvertfald så godt som jeg nu kan - jeg hader `gnidder` :) - så hvis min ide med at lave en property på min question-class, som bruges til at vise den med den rette type control, er en fornuftig måde at lave det på, så må det være vejen. Men ja, det er selvfølgelig ikke den endelige løsning bare at lave en property.. de andre ting skal jo også laves ordentligt.

Jeg skal jo på en eller anden måde ha tjekket brugerens input, og det er netop en af de ting jeg er lidt bange for. Det der det med at skulle referere til controls som bliver genereret dynamisk.. det er jo lidt... ja..umiddelbart har jeg ikke nogen ide til hvordan søren jeg skal kunne checke brugerens input, når jeg ikke ved hvor mange eller hvilken type controls der er blevet genereret - eller hmm ..  .. jeg sidder tænker på at lave min egen question-control. som kan tage X antal questions - fx en question-collection, såfremt jeg ønsker flere spørgsmål på een side. Men igen.. så er det der med at skulle tjekke brugerens svar som jeg ikke umiddelbart kan se løsningen på.. - men vil det være en dårlig ide?

Mvh
Peder
Avatar billede snepnet Nybegynder
13. juli 2005 - 09:48 #28
hej pede :o)

gentagelseskonroller behøver du ikke gøre så meget for - der findes både DataGrid, DataList og Repeater. de er som udgangspunkt rimelig gode, og du kan altid specialisere dem hvis du vil.

det er ikke så slemt at holde styr på brugerens input - tag f.eks. den fra før, og udvid den med at den skal gøre et eller andet når teksten i den ændres.

public class QuestionControl : WebControl, INamingContainer
{
  private Question question;
  private Label lblQuestion;
  private TextBox txtAnswer;

  public QuestionControl(Question question)
  {
    this.question = question;
  }

  protected override void CreateChildControls()
  {
    lblQuestion = new Label();
    lblQuestion.Text = question.QuestionText;
    Controls.Add(lblQuestion);

    txtAnswer = new TextBox();
    if(question.State == QuestionState.Answered)
    {
      txtAnswer.Enabled = false;
    }
    else
    {
      txtAnswer += new EventHandler(txtAnswer_Changed);
    }
    Controls.Add(txtAnswer);
   
    ChildControlsCreated = true;
  }

  protected void txtAnswer_Changed(object sender, EventArgs e)
  {
    // ... her kan du så gøre noget
  }
}

Men .... vær opmærksom på, at validering er en "indbygget mulighed", og du kan se det ved at du på dit page-objekt har

.Validate()
.IsValid

metoden Validate() kan du kalde som du har lyst til, og den sørger for at kontroller der implementerer et interface der hedder IValidator får kaldt deres Validate().

der er nogle eksisterende validatorer i din toolbox i forvejen, men der er ikke noget der forhindrer dig i, at implementere IValidator på dine egne kontroller, og på den måde få dem til at indgå i valideringen på samme måde som de andre.
det er et meget enkelt interface at implementere : 2 properties (IsValid og ErrorMessage) og en enkelt metode (Validate).

...

som sagt - der er mange måder at løse opgaven på, og der er forskellige typer af shortcuts.
f.eks. kunne du angive direkte på dine domæneklasse (som Question-klassen) hvordan du kunne tænke dig at få klassens properties at se i forbindelse med en præsentation(?!?) - et tænkt eksempel:

[RenderAs(PresentationType.TextBox)]
public string Question{...}

hvilket så i sidste ende gerne skulle medføre, at der blev vist en TextBox på siden (kræver self. en del kode + at vi bevæger os ind i et nyt område : reflection).

...

kan du ikke skrive lidt om hvor stor forskel du regner med der kan komme til at blive på den måde spørgsmålene skal vises på?

mvh
Avatar billede pede15 Nybegynder
13. juli 2005 - 10:01 #29
Well, jo det var vist en god ide hehe - ok, jeg har ikke helt 100% styr på antallet af måder, men 3 eller 4 forskellige måder.. men her snakker jeg så blot placering af "Answer" controllen i forhold til question (teksten) ... jeg har kun brug for to typer svar-controls - TextBox og DropDownList.. men kan også nøjes med TextBox - men mht. de forskellige måder at vise dem på så er det som sagt placeringen - skal TextBox stå inde i sætningen (udfyld det manglende ord-style), sammelinje eller under spørgsmålet. Men er det ikke bare at lave en metode til hver visnings-måde og så bruge HtmlTable ?
Avatar billede snepnet Nybegynder
13. juli 2005 - 10:10 #30
hmmm.... det lyder egentlig som det er meget lidt der skal til, og det med parseren kan jeg bedre forstå nu tror jeg - men lige for at være sikker.. er det sådan noget i denne stil du skal kunne angive så (pseudo):

"På panden steges der [TextBox] og [DropDownList[Bacon,Kartofler,Salat]]"

mvh
Avatar billede pede15 Nybegynder
13. juli 2005 - 10:10 #31
Hov forresten, den ide med at Implementere IValidator kan jeg godt lide - Vil det  ikke også give nogle fordele?

Mvh
Peder
Avatar billede snepnet Nybegynder
13. juli 2005 - 10:15 #32
det kunne det godt gøre - og det er som sagt rimelig enkelt, så jeg synes bestemt det er et forsøg værd... og hvis den måde spørgsmålene stilles op på er så enkle som jeg har forstået det du skrev, behøver du sådan set kun at lave en enkelt kontrol der kan parse din tekst til et kontroltræ - det er meget enkelt.
mvh
Avatar billede pede15 Nybegynder
13. juli 2005 - 10:20 #33
meget enkelt? Oo hehe - åårh det var sq at rart at høre :D - troede jeg havde kastet mig ud i det helt store komplekse system! ... puha..

Jeg kan prøve at give en beskrivelse af det forløb jeg forstiller mig spørgsmålet gennemgår fra det bliver hentet i databasen og til det ender hos brugeren.. hvis det kan være til hjælp?
Avatar billede snepnet Nybegynder
13. juli 2005 - 10:22 #34
det kan det bestemt.
mvh
Avatar billede pede15 Nybegynder
13. juli 2005 - 10:32 #35
Okay, jeg vil forsøge at beskrive det så godt som jeg kan.

Nu er det jo kun point.. eeh jeg håber virkelig ikke at du føler at du bliver udnyttet eller at jeg bare ikke gider at lave noget selv.. men sagen er den at jeg er under tidspres.. jeg har skudt ved siden af.. troede jeg kunne lave det her på ingen tid, men deeet.. - så din hjælp er modtaget med kyshånd :)

nu til beskrivelsen.
Avatar billede snepnet Nybegynder
13. juli 2005 - 10:37 #36
tidspres - crap... troede det var noget du sad og hyggede lidt med...
hvis du har en messengerkonto, så skriv den her - så kan vi tage den over messenger - det går lidt hurtigere, og vi kan lægge det herud bagefter.
mvh
Avatar billede pede15 Nybegynder
13. juli 2005 - 10:40 #37
babyboom63@hotmail.com

Du aner slet ikke hvor taknemlig jeg er :)
Avatar billede snepnet Nybegynder
13. juli 2005 - 14:44 #38
principskitse (ikke just releasekode) :

// aspx-fil
<%@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="PederSample._Default" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    <HEAD>
        <title>Default</title>
        <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
        <meta name="CODE_LANGUAGE" Content="C#">
        <meta name="vs_defaultClientScript" content="JavaScript">
        <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
    </HEAD>
    <body>
        <form id="Form1" method="post" runat="server">
            <P>
                <asp:Repeater id="rpQuestions" runat="server">
                    <HeaderTemplate>
                        <b>List of questions</b><br>
                        <br>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <asp:Label ID="lblQuestionId" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.QuestionId") %>'>
                        </asp:Label>                   
                        <asp:Label ID="lblQuestionText" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.QuestionText") %>'>
                        </asp:Label>
                        <asp:PlaceHolder ID="phQuestionControls" Runat="server"></asp:PlaceHolder>
                        <asp:Button ID="btnAnswer" Runat="server" Text="Besvar" CommandName="ANSWER" CommandArgument='<%# DataBinder.Eval(Container, "DataItem.QuestionId") %>'>
                        </asp:Button>
                    </ItemTemplate>
                    <SeparatorTemplate>
                        <hr>
                    </SeparatorTemplate>
                </asp:Repeater></P>
            <P>
                <asp:Button id="btnAnswerAll" runat="server" Text="Besvar"></asp:Button></P>
        </form>
    </body>
</HTML>

// code-behind
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 PederSample
{
    public class _Default : System.Web.UI.Page
    {
        protected System.Web.UI.WebControls.Button btnAnswerAll;
        protected System.Web.UI.WebControls.Repeater rpQuestions;

        protected QuestionCollection Questions
        {
            get
            {
                return Session["Questions"] as QuestionCollection;
            }
            set
            {
                Session["Questions"] = value;
            }
        }
   
        private void Page_Load(object sender, System.EventArgs e)
        {
            if(!IsPostBack)
            {
                Questions = new QuestionCollection();
                for(int i=0;i<10;i++)
                {
                    Questions.Add(new Question(i, String.Format("Spørgsmål nummer {0}", i)));
                }               
            }
            BindRepeater();
        }

        private void BindRepeater()
        {
            if(Questions != null)
            {
                rpQuestions.DataSource = Questions;
                rpQuestions.DataBind();
            }
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);
        }
       
        private void InitializeComponent()
        {   
            this.rpQuestions.ItemDataBound += new System.Web.UI.WebControls.RepeaterItemEventHandler(this.rpQuestions_ItemDataBound);
            this.rpQuestions.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.rpQuestions_ItemCommand);
            this.btnAnswerAll.Click += new System.EventHandler(this.btnAnswerAll_Click);
            this.Load += new System.EventHandler(this.Page_Load);

        }
        #endregion

        private void rpQuestions_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
        {
            if(e.CommandName == "ANSWER")
            {
                // lidt haxet - bare så du kan se at du kan få fat i det... Response.Write bør ikke bruges
                Response.Write(String.Format("Spørgsmål nummer {0} er blevet besvaret<br>", e.CommandArgument));
            }
        }

        private void rpQuestions_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                Question q = e.Item.DataItem as Question;
                PlaceHolder ph = e.Item.FindControl("phQuestionControls") as PlaceHolder;
               
                switch(q.QuestionType)
                {
                    case QuestionTypes.Type1 :
                        TextBox tb = new TextBox();
                        tb.ID="ctrlAnswer";
                        tb.Text = q.Answer;
                        if(q.QuestionState == QuestionStates.Answered)
                            tb.Enabled = false;
                        ph.Controls.Add(tb);
                        break;
                    case QuestionTypes.Type2:
                        DropDownList ddList = new DropDownList();
                        ddList.ID = "ctrlAnswer";                       
                        ddList.Items.Add("svar1");
                        ddList.Items.Add("svar2");
                        ddList.Items.Add("svar3");
                        foreach(ListItem li in ddList.Items)
                        {
                            if(li.Text == q.Answer)
                                li.Selected = true;
                        }
                        ddList.Items.Insert(0,"choose");
                        if(q.QuestionState == QuestionStates.Answered)
                        {
                            ddList.Enabled = false;
                        }
                        ph.Controls.Add(ddList);                       
                        break;
                    default :
                        throw new ApplicationException("unknown questiontype");
                }               
            }
        }

        private void btnAnswerAll_Click(object sender, System.EventArgs e)
        {           
            bool unvalidatedQuesetons = false;
            foreach(RepeaterItem item in rpQuestions.Items)
            {
                Label lblQuestionid = item.FindControl("lblQuestionId") as Label;
                int questionId = int.Parse(lblQuestionid.Text);
                Question question = Questions.GetQuestion(questionId);
                string answer = String.Empty;
               
                if(question.QuestionType == QuestionTypes.Type1)
                {
                    // find tekstboksen
                    object o = item.FindControl("ctrlAnswer");
                    answer = ((TextBox)item.FindControl("ctrlAnswer")).Text;
                }
                else if(question.QuestionType == QuestionTypes.Type2)
                {
                    // find listen
                    string _answer = ((DropDownList)item.FindControl("ctrlAnswer")).SelectedItem.Text;
                    answer = _answer != "choose" ? _answer : String.Empty;
                }
               
                question.Answer = answer;
               
                if(question.IsValid)
                {
                    question.QuestionState = QuestionStates.Answered;
                }
                else
                {
                    unvalidatedQuesetons = true;
                }
               
            }
            // binding igen da tilstand er ændret
            BindRepeater();
           
            // ... gem sagerne

            if(!unvalidatedQuesetons)
                Response.Write("You are done! - continue to next page");
            else
                Response.Write("You are not done! - fix errors");
        }
    }

    public class QuestionCollection : CollectionBase
    {
        public Question this[int index]
        {
            get{return List[index] as Question;}
            set{List[index] = value;}
        }
       
        public int Add(Question question)
        {
            return List.Add(question);
        }

        public Question GetQuestion(int questionId)
        {
            foreach(Question question in List)
            {
                if(question.QuestionId == questionId)
                {
                    return question;
                }
            }
            return null;
        }
    }
   
    public enum QuestionTypes
    {
        Type1,
        Type2
    }

    public enum QuestionStates
    {
        New,
        Answered
    }

    public class Question
    {
        private QuestionStates _questionState;
        private QuestionTypes _questionType;
        private string _questionText;
        private int _questionId;
        private string _answer;

        public bool IsValid
        {
            get
            {
                if(Answer.Trim().Length > 0)
                    return true;
                return false;
            }
        }

        public string QuestionText
        {
            get{return _questionText;}
            set{_questionText = value;}
        }

        public string Answer
        {
            get{return _answer;}
            set{_answer = value;}
        }

        public int QuestionId
        {
            get{return _questionId;}
        }

        public QuestionTypes QuestionType
        {
            get{return _questionType;}
        }
       
        public QuestionStates QuestionState
        {
            get{return _questionState;}
            set{_questionState = value;}
        }
       
        public Question(int questioinId, string questionText)
        {
            this._questionId = questioinId;
            this._questionText = questionText;

            if(QuestionId %2 == 0)
                _questionType = QuestionTypes.Type1;
            else
                _questionType = QuestionTypes.Type2;
        }
    }
}

mvh
Avatar billede pede15 Nybegynder
21. juli 2005 - 23:26 #39
Mange tak for hjælpen snepnet! - Det bliver ganske godt - og jeg når det :)

- læg et svar så du kan få dine velfortjente point!

Mvh
Peder
Avatar billede snepnet Nybegynder
22. juli 2005 - 09:16 #40
får du her :o)
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