Avatar billede tinaw25 Nybegynder
08. oktober 2013 - 16:38 Der er 50 kommentarer og
2 løsninger

Hvordan styre man at en vare tæller mere end andre?

Hej

Jeg kunne godt tænke mig lidt hjælp, og vejledning.

En bruger skal have mulighed for at vælge mellem 12 forskellige frugter og må max. vælge 7 stk. Jeg troede jeg kunne løse det med at lave en repeater, hvor der var textboxe hvor brugeren indtastede det ønskede antal.

Men jeg kan ikke lige se hvordan jeg skal få informationer på en anden side om, hvad brugeren har bestilt og hvilket antal?? Skal jeg have noget indkøbskurv lignende bare uden priser??

Men samtidig er der nogle frugter, som tæller for 7 stk.

/Tina
Avatar billede anri Novice
08. oktober 2013 - 21:26 #1
Har du systemet kørende ovenpå en database?
Avatar billede anri Novice
08. oktober 2013 - 21:27 #2
Du kan gemme informationerne i en cookie.
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 09:13 #3
Ja, jeg har en database. Jeg har prøvet at gøre noget i denne her stil, for at jeg kunne gemme i session antal frugt og hvilken frugt kunden har bestilt. Men jeg kan ikke lige se hvad jeg mangler og hvad jeg skal gøre ved at en melon tæller 7 stk frugt.

protected void Button1_Click1(object sender, EventArgs e)
    {

        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = item.FindControl("txtbox1") as TextBox;

                // opret forbindelsen til databasen
                SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());

                // opret et SqlCommand object
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = conn;

                //Sql sætningen
                cmd.CommandText = "INSERT INTO frugt (frugt_navn) VALUES(@frugt)";


                cmd.Parameters.Add("@frugt", SqlDbType.VarChar).Value = Session["frugt"];
             
               
                if (Textbox_antal != null)
                {
                    if (string.IsNullOrEmpty(Textbox_antal.Text))
                    {
                        Textbox_antal.Text = "0";
                    }
                }


                Value = Convert.ToInt32(Value + int.Parse(Textbox_antal.Text));
                Session["frugt_antal"] = Value;

                if (Value != 7)
                {
                    Label1.Text = "Der er 7 nu";
                    Panel_visfrugt.Visible = false;
                    Panel_vis.Visible = true;

                }
                else if (Value > 7)
                {
                    Label1.Text = "Det er kun muligt at bestille 7 stk frugt";

                }
            }           
        }
     
            Label_vis.Text = Convert.ToString(Session["frugt"]);
            Label_vis.Text = Convert.ToString(Session["frugt_antal"]);
       
       
         
             
    }
/ Tina
Avatar billede anri Novice
09. oktober 2013 - 13:52 #4
Nu kommer jeg lige med en masse antagelser:

Jeg antager at du har en database-tabel med typen af frugt, og hvor mange frugter de tæller for.  Eks.
ID | Frugt | Vaerdi
01 | Banan | 2
02 | Æble | 1
03 | Melon | 7

Så antager jeg også at du udfylder din repeater fra denne tabel.

Jeg kan dog ikke helt gennemskue hvad du vil med den tabel du kalder "frugt", men for at komme tættere på løsningen, har jeg lavet lidt om i din kode og skrevet kommentarer, så må vi tage den derfra.

Først vil jeg abbonere på repeaterens ItemDataBound event, for at lade hver frugts textBox have en værdi.

protected void Repeater1_ItemDataBound(object sender, EventArgs e){
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
        TextBox Textbox_antal = item.FindControl("txtbox1") as TextBox;
        if (Textbox_antal == null) return;

        Textbox_antal.Attributes.Add("FrugtID", ((DataRow)e.Item.DataItem)["ID"]); //Læg en ny attribut på TextBoxen der peger på frugtens unikke ID. 
        Textbox_antal.Attributes.Add("FrugtVaerdi", ((DataRow)e.Item.DataItem)["Vaerdi"]); //Læg en ny attribut på TextBoxen der peger på vaerdi.
    }
}

Nu har du frugtens unikke ID og vaerdi stemplet på frugtens egen TextBox;


protected void Button1_Click1(object sender, EventArgs e)
    {
    int totalvaerdi= 0;
        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = item.FindControl("txtbox1") as TextBox;
        if (Textbox_antal == null) continue; //Tekstboksen blev ikke fundet, så ingen grund til at lave mere her.

                // opret forbindelsen til databasen
        int enkeltFrugtVaerdi = int.parse(Textbox_antal.Attributes["Vaerdi"]);
        int enkeltFrugtAntal = int.parse(Textbox_antal.Text);
       
        totalvaerdi += (enkeltFrugtVaerdi * enkeltFrugtAntal );

        //Hvis du skal gemme bestillingen af den enkelte frugt, skal det gøres her.
            }           
        }
     
    //Totalen på bestillingen og check om de 7 overstiges, checkes her.
    //Du skal nok også vente med at lægge bestillinger i databasen, til du har kontrolleret at værdien ikke overstiges.
         
             
    }
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 13:58 #5
Jeg har sådan en tabel du snakket om, har bare ikke sat en værdi ind som så er den måde jeg skal styre hvilken værdi de har, har ikke rigtig prøvet at lave det før nemlig.

Jeg kigger på koden i aften, er på vej ud af døren
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 21:11 #6
De her to er der røde streger? Men skal det ikke være ToString() bagefter??

Textbox_antal.Attributes.Add("frugt_id", ((DataRow)e.Item.DataItem)["frugt_id"]); //Læg en ny attribut på TextBoxen der peger på frugtens unikke ID. 
            Textbox_antal.Attributes.Add("vaerdi", ((DataRow)e.Item.DataItem)["vaerdi"]); //Læg en ny attribut på TextBoxen der peger på vaerdi.

Min næste spørgsmål, er at når jeg tjekker totalværdien at den er 7 så skal den lukke panel ned og tage det man lige har bestilt med over og vise? Er det så med en session??

if (totalvaerdi != 7)
        {
            Label_vis.Text = "Nu er der 7";
            Panel_visfrugt.Visible = false;
            Panel_vis.Visible = true;

        }
        else
        {

            Label_vis.Text = "Du kan kun bestille 7 stk frugt";
        }
Avatar billede anri Novice
09. oktober 2013 - 21:27 #7
Jo, det har du ret i.

Brug string.format("{0}", ((DataRow)....

..så fungerer den også hvis værdien er null.
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 21:31 #8
Det vil den ikke have ind der
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 21:33 #9
Det var sådan her du mente

Textbox_antal.Attributes.Add("FrugtID", string.format({"0"}), ((DataRow)e.Item.DataItem)["frugt_id"]);
Avatar billede anri Novice
09. oktober 2013 - 21:57 #10
Textbox_antal.Attributes.Add("FrugtID", string.format("{0}", ((DataRow)e.Item.DataItem)["frugt_id"]);
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 22:04 #11
Fandt ud af det var min fejl, men når jeg indtaster nogle tal tekstbox brokker den sig over denne her?


Value cannot be null.
Parameter name: String

Line 42: int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["vaerdi"]);


Line 43: int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);

Vel det samme problem som den anden, men her kan jeg vel bare bruge ToString??

Men hvordan får jeg hvis jeg vælger:
2 bananer, 2 æbler, 3 blommer i det ene panel til at åbne i det andet panel og rent faktisk vise hvad det er man har bestilt? Er det i en session?

For først når man kommer over i det andet panel vil jeg ligge det ind i databasen.
Avatar billede anri Novice
09. oktober 2013 - 22:23 #12
Kan du ikke se nogle attributes på Textbox_antal når du læser dem igen? (prøv at kigge efter i debuggeren)

Jeg ville gemme valget i databasen på det tidspunkt jeg har angivet i besked #4 og så læse dem igen på bekræftelses-siden.
Avatar billede anri Novice
09. oktober 2013 - 22:26 #13
Men ja. 
Der er mange steder du kan gemme det.
Du kan bruge en cookie, eller session-variabler.

Du kan også sætte det in i query-strengen, bekraeft.aspx?bananer=2&aebler=2&blommer=3&bananer=0
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 22:45 #14
Value siger 0 i debug.

Ville du så give brugeren mulighed for at ændre i bestillingen hvis man nu har valgt forkert?

Er dette her korrekt?
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            TextBox Textbox_antal = FindControl("txtbox1") as TextBox;
            if (Textbox_antal == null) return;

            Textbox_antal.Attributes.Add("FrugtID", string.Format("{0}", ((DataRow)e.Item.DataItem)["frugt_id"])); //Læg en ny attribut på TextBoxen der peger på frugtens unikke ID. 
            Textbox_antal.Attributes.Add("FrugtVaerdi", string.Format("{0}", ((DataRow)e.Item.DataItem)["vaerdi"])); //Læg en ny attribut på TextBoxen der peger på vaerdi.
           
        }
    }

    protected void Button1_Click1(object sender, EventArgs e)
    {
        int totalvaerdi = 0;
        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = item.FindControl("txtbox1") as TextBox;
                if (Textbox_antal == null) continue; //Tekstboksen blev ikke fundet, så ingen grund til at lave mere her.

                // opret forbindelsen til databasen
               


                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["vaerdi"]);
                int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);

                totalvaerdi += (enkeltFrugtVaerdi * enkeltFrugtAntal);

             

               
                //Hvis du skal gemme bestillingen af den enkelte frugt, skal det gøres her.
            }
        }
        if (totalvaerdi != 7)
        {
           
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandText = "INSERT INTO ordre (ordre_navn, ordre_antal) VALUES(@navn, @antal)";
            cmd.Parameters.Add("@navn", SqlDbType.VarChar).Value = ;
            cmd.Parameters.Add("@antal", SqlDbType.VarChar).Value = Ved ikke lige hvad jeg skal skrive her;



            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();
            Response.Redirect("bekraft.aspx");

        }
        else
        {

            Label_vis.Text = "Du kan kun bestille 7 stk frugt";
        }
        //Totalen på bestillingen og check om de 7 overstiges, checkes her.
        //Du skal nok også vente med at lægge bestillinger i databasen, til du har kontrolleret at værdien ikke overstiges.
    }
Avatar billede anri Novice
09. oktober 2013 - 22:59 #15
Næsten.
Her, hvor du forsøger at læse værdien
                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["vaerdi"]);
Der har du jo kaldt attributten "varedi" men der hvor du sætter den kalder du den "FrugtVaerdi"
Avatar billede anri Novice
09. oktober 2013 - 23:02 #16
Angående om jeg ville lade brugeren vælge om er vel et design og ikke et kode-spørgsmål.
Det kunne jo være så simpelt som at lægge en "tilbage" knap på.
Avatar billede tinaw25 Nybegynder
09. oktober 2013 - 23:28 #17
Den kommer stadigvæk med en en fejl, der kommer ingen værdi i.

int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);

Jeg har tilføjet en attribut med navnet, så jeg kan få det med er det korrekt??
Gider du at kigge op koden er rigtig nu, tænker lidt på oprettelsen til databasen er lidt i tvivl om jeg har valgt de rigtige ting.

Jeg har aldrig prøvet det med attributer før. Eller slet ikke leget med så advanceret kode før.

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            TextBox Textbox_antal = FindControl("txtbox1") as TextBox;
            if (Textbox_antal == null) return;

            Textbox_antal.Attributes.Add("FrugtID", string.Format("{0}", ((DataRow)e.Item.DataItem)["frugt_id"])); //Læg en ny attribut på TextBoxen der peger på frugtens unikke ID. 
            Textbox_antal.Attributes.Add("FrugtVaerdi", string.Format("{0}", ((DataRow)e.Item.DataItem)["vaerdi"])); //Læg en ny attribut på TextBoxen der peger på vaerdi.
            Textbox_antal.Attributes.Add("FrugtNavn", string.Format("{0}", ((DataRow)e.Item.DataItem)["frugt_navn"])); //Læg en ny attribut på TextBoxen der peger på vaerdi.
           
        }
    }

    protected void Button1_Click1(object sender, EventArgs e)
    {
        int totalvaerdi = 0;
        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = item.FindControl("txtbox1") as TextBox;
                if (Textbox_antal == null) continue; //Tekstboksen blev ikke fundet, så ingen grund til at lave mere her.

                // opret forbindelsen til databasen
                SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
                int frugtNavn = Convert.ToInt32(Textbox_antal.Attributes["FrugtNavn"]);
                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);
                int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);

                totalvaerdi += (enkeltFrugtVaerdi * enkeltFrugtAntal);

                cmd.CommandText = "INSERT INTO ordre (ordre_navn, ordre_antal, fk_frugt_id) VALUES(@navn, @antal, @frugt)";
                cmd.Parameters.Add("@navn", SqlDbType.VarChar).Value = frugtNavn;
                    cmd.Parameters.Add("@antal", SqlDbType.VarChar).Value = totalvaerdi;
                    cmd.Parameters.Add("@frugt", SqlDbType.VarChar).Value = ;
             
           
               
                conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();
               
                //Hvis du skal gemme bestillingen af den enkelte frugt, skal det gøres her.
            }
        }
        if (totalvaerdi != 7)
        {
           
            SqlConnection conn = new SqlConnection();
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandText = "INSERT INTO ordre (ordre_navn, ordre_antal, fk_frugt_id) VALUES(@navn, @antal, @frugt)";
            cmd.Parameters.Add("@navn", SqlDbType.VarChar).Value = aner ikke hvad jeg skal skrive her;
            cmd.Parameters.Add("@antal", SqlDbType.VarChar).Value = aner ikke hvad jeg skal skrive her;
            cmd.Parameters.Add("@frugt", SqlDbType.VarChar).Value = aner ikke hvad jeg skal skrive her;


         
            conn.Open();
            cmd.ExecuteNonQuery();
            conn.Close();
            Response.Redirect("bekraft.aspx");
         
        }
        else
        {

            Label_vis.Text = "Du kan kun bestille 7 stk frugt";
        }
        //Totalen på bestillingen og check om de 7 overstiges, checkes her.
        //Du skal nok også vente med at lægge bestillinger i databasen, til du har kontrolleret at værdien ikke overstiges.
    }
Avatar billede anri Novice
10. oktober 2013 - 08:46 #18
Nå..  Nu fik du mig sgu til at starte visual studio op ;-)

Hermed fungerende kode med kommentarer.


        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack) //Hvis det er en PostBack (knappen er trykket), så skal data ikke bindes igen.
            {
                Repeater1.DataSource = MakeMockTable();
                Repeater1.DataBind();
            }
        }

        private static DataTable MakeMockTable() //Bare nogle test-data.  Du får dem jo fra databasen
        {
            DataTable worktbl = new DataTable();
            worktbl.Columns.Add("frugt_id", typeof(int));
            worktbl.Columns.Add("vaerdi", typeof(int));
            worktbl.Columns.Add("frugt_navn", typeof(string));

            DataRow workRow = worktbl.NewRow();
            workRow["frugt_id"] = 0;
            workRow["vaerdi"] = 1;
            workRow["frugt_navn"] = "Banan";
            worktbl.Rows.Add(workRow);
            workRow = worktbl.NewRow();
            workRow["frugt_id"] = 1;
            workRow["vaerdi"] = 1;
            workRow["frugt_navn"] = "Æble";
            worktbl.Rows.Add(workRow);
            workRow = worktbl.NewRow();
            workRow["frugt_id"] = 2;
            workRow["vaerdi"] = 1;
            workRow["frugt_navn"] = "Blomme";
            worktbl.Rows.Add(workRow);
            workRow = worktbl.NewRow();
            workRow["frugt_id"] = 3;
            workRow["vaerdi"] = 7;
            workRow["frugt_navn"] = "Melon";
            worktbl.Rows.Add(workRow);
            return worktbl;
        }
        protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = e.Item.FindControl("TextBox1") as TextBox; //Her søgte du ikke efter control'en i e.Item og derfor fik du ikke fat i nogen TextBox og den exitede i næste linie
                if (Textbox_antal == null) return;

                Textbox_antal.Attributes.Add("FrugtID", string.Format("{0}", ((DataRowView)e.Item.DataItem)["frugt_id"])); //DataRow typecast ændret til DataRowView.
                Textbox_antal.Attributes.Add("FrugtVaerdi", string.Format("{0}", ((DataRowView)e.Item.DataItem)["vaerdi"])); //...i alle 3 linier
                Textbox_antal.Attributes.Add("FrugtNavn", string.Format("{0}", ((DataRowView)e.Item.DataItem)["frugt_navn"]));

            }
        }

        protected void Button1_Click1(object sender, EventArgs e)
        {
            int totalvaerdi = 0;
            List<ValgtFrugt> valgteFrugter = new List<ValgtFrugt>(); //Her laver jeg en liste over valgte frugter. Det er et nyt objekt, som kan indeholde påde ID, Navn, Antal og Værdi

            foreach (RepeaterItem item in Repeater1.Items)
            {
                if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
                {
                    TextBox Textbox_antal = item.FindControl("TextBox1") as TextBox;
                    if (Textbox_antal == null) continue; //Tekstboksen blev ikke fundet, så ingen grund til at lave mere her.

                    string frugtNavn = Textbox_antal.Attributes["FrugtNavn"]; //Det her skal vel være en streng!?
                    int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);
                    int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);

                    totalvaerdi += (enkeltFrugtVaerdi * enkeltFrugtAntal);

                    if (enkeltFrugtAntal > 0)
                    {
                        ValgtFrugt frugtenDerskalTilfoejes = new ValgtFrugt(); //Opret frugten og angiv værdier
                        frugtenDerskalTilfoejes.FrugtNavn = frugtNavn;
                        frugtenDerskalTilfoejes.Vaerdi = enkeltFrugtVaerdi;
                        frugtenDerskalTilfoejes.Antal = enkeltFrugtAntal;
                        valgteFrugter.Add(frugtenDerskalTilfoejes);
                    }
                }
            }

            if (totalvaerdi <= 7) //Det her skal vel være "Mindre end" eller lig 7, for ellers kan du bestille over 7 frugter
            {
                Session["ValgteFrugter"] = valgteFrugter; //Her lægger jeg dem bare i en session-variabel, så kan jeg lægge dem ind i databasen når det er bekræftet.


                Response.Redirect("bekraeft.aspx");

            }
            else
            {

                Label_vis.Text = "Du kan kun bestille 7 stk frugt";
            }
        }

        private class ValgtFrugt //Et objekt der beskriver en valgt frugt
        {
            public int ID { get; set; }
            public string FrugtNavn { get; set; }
            public int Antal { get; set; }
            public int Vaerdi { get; set; }
        }
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 09:48 #19
Er det mig der er dum eller hvad?

Men på bekraft.aspx når jeg vil vise min session, så skal jeg sgu da gøre det sådan her ikke?

protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = Session["ValgteFrugter"].ToString();
       
    }

Så viser den dette her på siden?

System.Collections.Generic.List`1[Default2+ValgtFrugt]
Avatar billede anri Novice
10. oktober 2013 - 10:16 #20
Første spørgsmål, skal jeg ikke kunne svare på, det kunne jo også være at du bare ikke har programmeret siden du var 10 år gammel ;-)

Sessionsvariablen indeholder nu listen over valgte frugter, så du skal hente den således:

List<ValgtFrugt> valgteFrugter = (List<ValgtFrugt>)Session["ValgteFrugter"];

Så kan du gennemløbe listen med
foreach(ValgtFrugt frugt in valgteFrugter ){
  //Variablen "frugt" indeholder nu hvert enkelt valgtfrugt objekt og nu kan du gøre sådan:
Label1.Text += string.format("{0} ({1} stk.)", frugt.FrugtNavn, frugt.Antal);

//Du kan selvfølgelig også lave beregninger på dem og lægge resultatet i databasen

}

Du skal nok have lagt ValgtFrugt klassen ud hvor den kan ses af alle sider (i sin egen class)
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 10:34 #21
Har kun kodet 1 års tid, så nok derfor :-)

Lige nu ser det sådan her ud

private class ValgtFrugt //Et objekt der beskriver en valgt frugt
    {
        public int ID { get; set; }
        public string FrugtNavn { get; set; }
        public int Antal { get; set; }
        public int Vaerdi { get; set; }
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        List<ValgtFrugt> valgteFrugter = (List<ValgtFrugt>)Session["ValgteFrugter"];
        foreach (ValgtFrugt frugt in valgteFrugter)
        {
            //Variablen "frugt" indeholder nu hvert enkelt valgtfrugt objekt og nu kan du gøre sådan:
            Label1.Text += string.Format("{0} ({1} stk.)", frugt.FrugtNavn, frugt.Antal);
        }

    }

Og den kommer med denne fejl:
Unable to cast object of type 'System.Collections.Generic.List`1[Default2+ValgtFrugt]' to type 'System.Collections.Generic.List`1[bekraeft+ValgtFrugt]'.

Line 17:    protected void Page_Load(object sender, EventArgs e)
Line 18:    {
Line 19:        List<ValgtFrugt> valgteFrugter = (List<ValgtFrugt>)Session["ValgteFrugter"];
Line 20:        foreach (ValgtFrugt frugt in valgteFrugter)
Line 21:        {
Avatar billede anri Novice
10. oktober 2013 - 10:46 #22
Ja jeg tænkte det nok.
Selvom de to objekt-klasser ser ens ud, så betragter kompileren dem som forskellige (og det skal den også.

For at dele en klasse over 2 forskellige sider, skal du enten trække den ud i sin egen [klasse].cs fil (Højreklik projekt, add, class) og referere til den fra både default2.aspx.cs og bekraeft.aspx.cs ELLER..

Jeg TROR du kan lave den public i Default2.aspx.cs og referere til den via Default02.ValgtFrugt (Men det er noget rode-kode)
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 11:23 #23
Jeg har fået class på siden, men når jeg vælger frugt viser den en tom side
Avatar billede anri Novice
10. oktober 2013 - 11:39 #24
Så må jeg jo se koden
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 11:40 #25
public ValgtFrugt frugtKurv;
    protected void Page_Load(object sender, EventArgs e)
    {
        List<ValgtFrugt> valgteFrugter = (List<ValgtFrugt>)Session["ValgteFrugter"];
        foreach (ValgtFrugt frugt in valgteFrugter)
        {
            //Variablen "frugt" indeholder nu hvert enkelt valgtfrugt objekt og nu kan du gøre sådan:
            Label1.Text += string.Format("{0} ({1} stk.)", frugt.FrugtNavn, frugt.Antal);
        }

    }
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 11:42 #26
DEfault2 siden:

Man skal vælge 7 så den skal være Equal to 7. Men den går ikke ind og tager værdien fra f.eks melon og går til næste side eller hvis man vælger 7 af de andre

public ValgtFrugt frugtKurv;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack) //Hvis det er en PostBack (knappen er trykket), så skal data ikke bindes igen.
        {
            //// opret forbindelsen til databasen
            //SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());

            //// opret et SqlCommand object
            //SqlCommand cmd = new SqlCommand();
            //cmd.Connection = conn;

            //  cmd.CommandText = @"SELECT * FROM frugt";


            //DataTable visProdukter = new DataTable();
            //SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            //adapter.Fill(visProdukter);
            //Repeater1.DataSource = visProdukter;
            //Repeater1.DataBind();

            //conn.Close();
            Repeater1.DataSource = MakeMockTable();
            Repeater1.DataBind();
        }
    }
    private static DataTable MakeMockTable() //Bare nogle test-data.  Du får dem jo fra databasen
    {


        DataTable worktbl = new DataTable();
        worktbl.Columns.Add("frugt_id", typeof(int));
        worktbl.Columns.Add("vaerdi", typeof(int));
        worktbl.Columns.Add("frugt_navn", typeof(string));

        DataRow workRow = worktbl.NewRow();
        workRow["frugt_id"] = 0;
        workRow["vaerdi"] = 1;
        workRow["frugt_navn"] = "Banan";
        worktbl.Rows.Add(workRow);
        workRow = worktbl.NewRow();
        workRow["frugt_id"] = 1;
        workRow["vaerdi"] = 1;
        workRow["frugt_navn"] = "Æble";
        worktbl.Rows.Add(workRow);
        workRow = worktbl.NewRow();
        workRow["frugt_id"] = 2;
        workRow["vaerdi"] = 1;
        workRow["frugt_navn"] = "Blomme";
        worktbl.Rows.Add(workRow);
        workRow = worktbl.NewRow();
        workRow["frugt_id"] = 3;
        workRow["vaerdi"] = 7;
        workRow["frugt_navn"] = "Melon";
        worktbl.Rows.Add(workRow);
        return worktbl;
    }
    protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            TextBox Textbox_antal = FindControl("txtbox1") as TextBox;
            if (Textbox_antal == null) return;

            Textbox_antal.Attributes.Add("FrugtID", string.Format("{0}", ((DataRow)e.Item.DataItem)["frugt_id"])); //Læg en ny attribut på TextBoxen der peger på frugtens unikke ID. 
            Textbox_antal.Attributes.Add("FrugtVaerdi", string.Format("{0}", ((DataRow)e.Item.DataItem)["vaerdi"])); //Læg en ny attribut på TextBoxen der peger på vaerdi.
            Textbox_antal.Attributes.Add("FrugtNavn", string.Format("{0}", ((DataRow)e.Item.DataItem)["frugt_navn"])); //Læg en ny attribut på TextBoxen der peger på vaerdi.
           
        }
    }

    protected void Button1_Click1(object sender, EventArgs e)
    {
        int totalvaerdi = 0;
        List<ValgtFrugt> valgteFrugter = new List<ValgtFrugt>(); //Her laver jeg en liste over valgte frugter. Det er et nyt objekt, som kan indeholde påde ID, Navn, Antal og Værdi

        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = item.FindControl("TextBox1") as TextBox;
                if (Textbox_antal == null) continue; //Tekstboksen blev ikke fundet, så ingen grund til at lave mere her.

                string frugtNavn = Textbox_antal.Attributes["FrugtNavn"]; //Det her skal vel være en streng!?
                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);
                int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);

                totalvaerdi += (enkeltFrugtVaerdi * enkeltFrugtAntal);

                if (enkeltFrugtAntal > 0)
                {
                    ValgtFrugt frugtenDerskalTilfoejes = new ValgtFrugt(); //Opret frugten og angiv værdier
                    frugtenDerskalTilfoejes.FrugtNavn = frugtNavn;
                    frugtenDerskalTilfoejes.Vaerdi = enkeltFrugtVaerdi;
                    frugtenDerskalTilfoejes.Antal = enkeltFrugtAntal;
                    valgteFrugter.Add(frugtenDerskalTilfoejes);
                }
            }
        }

        if (totalvaerdi == 7) //Det her skal vel være "Mindre end" eller lig 7, for ellers kan du bestille over 7 frugter
        {
            Session["ValgteFrugter"] = valgteFrugter; //Her lægger jeg dem bare i en session-variabel, så kan jeg lægge dem ind i databasen når det er bekræftet.


            Response.Redirect("bekraeft.aspx");
            Label_vis.Text = "Virker det";

        }
        else
        {

            Label_vis.Text = "Du kan kun bestille 7 stk frugt";
        }
    }
Avatar billede anri Novice
10. oktober 2013 - 11:50 #27
Så bør du single-steppe dig igennem først default2.aspx for at sikre at du har data i den variabel, du har i det objekt du lægger i sessions variablen.

Sæt et breakpoint i Button1_Click1 og se hvad der sker.

Du kan for resten ikke sætte nogen label-tekst efter du har lavet en Response.Redirect, for den sender dig til en anden side.
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 12:06 #28
Tror jeg ligger det ind i en nyt website , nu vil den ikke vise siden

HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Avatar billede anri Novice
10. oktober 2013 - 12:10 #29
Nååh.
Det der siger den fordi du forsøger at kalde roden på en folder uden at referere direkte til en .aspx side.

På nogle servere kan man så fø en lister over filer i folderen, men det er noget af en sikkerhedsbrist, så de fleste siger bare "error 403.14"
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 12:13 #30
Den køre kun hertil og der er ingen værdi i


        int totalvaerdi = 0;
        List<ValgtFrugt> valgteFrugter = new List<ValgtFrugt>(); //Her laver jeg en liste over valgte frugter. Det er et nyt objekt, som kan indeholde påde ID, Navn, Antal og Værdi

        foreach (RepeaterItem item in Repeater1.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                TextBox Textbox_antal = item.FindControl("TextBox1") as TextBox;
                if (Textbox_antal == null) continue; //Tekstboksen blev ikke fundet, så ingen grund til at lave mere her.
Avatar billede anri Novice
10. oktober 2013 - 12:15 #31
Ok, så du får [null] i Textbox_antal, så er det måske fordi tekstboksen ikke hedder TextBox1 i repeateren.
C# skelner imellem store og små bogstaver.
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 12:23 #32
Den var forkert den hed noget andet i repeater.

Men nu går den i fejl på

Value cannot be null.
Parameter name: String

Line 96:
Line 97:                string frugtNavn = Textbox_antal.Attributes["FrugtNavn"]; //Det her skal vel være en streng!?
Line 98:                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);
Line 99:                int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);
Line 100:

Og der er stadigvæk ingen værdier i debug
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 12:25 #33
Er det fordi det er en varchar i databasen vaerdi
Avatar billede anri Novice
10. oktober 2013 - 12:38 #34
Hvilken linie fejler?

En varchar kan du godt parse til en int, men hvis ikke der står noget i den (null eller blank streng) så vil den funktion fejle. Så skal du enten teste på om den er null i databasen først, eller benytte int.TryParse funktionen
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 12:50 #35
Fejler på denne her

Line 98:                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);
Avatar billede anri Novice
10. oktober 2013 - 12:56 #36
Lidt sært.
Det fungerer fint i mit eksempel.
Hvis du kigger på den HTML kode der bliver genereret, kan du så ikke se de rigtige attributter med de rigtige værdier (her skelner den også mellem store og små bogstaver)
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 13:05 #37
Jeg kommer slet ikke over på den anden side, den fejler inden
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 13:39 #38
Nu har jeg kopieret det ind i et nyt website.

min cs fil hedder ValgtFrugt og den indeholder:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


public class ValgtFrugt
{

    public int ID { get; set; }
    public string FrugtNavn { get; set; }
    public int Antal { get; set; }
    public int Vaerdi { get; set; }

}

Er dette korrekt?
Avatar billede anri Novice
10. oktober 2013 - 13:53 #39
Tjooh, nu begynder det at blive lidt forvirrende at overskue for mig.

For lige at svare på #37 så vil jeg have dig til at kigge på HTML koden af default2.aspx, inden du trykker på knappen.

Her skal du sikre dig at de <input> tags der udgører tekstboksene, også har de rette værdier og attributter. Når man får nogle fejl man ikke kan gennemskue, er det en god idé at kontrollere al ting trin for trin.

1. Du genererer en liste med tekstbokse
- Har de nu de værdier du forventede?

2. Tekstboksene er genereret ok og du har trykket på "bestil" knappen.
- single-step click-eventen igennem linie for linie, og hvis den fejler, så prøv vurdere hvilken del af linien der fejler (har den ikke fundet det element man spørger på, er der en forkert værdi i elementet)
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 14:05 #40
I min HTML står der
Så det virker ikke som om at de får den rette atributter
<tr>
<td>Banan</td>
<td><input name="Repeater1$ctl100$txtbox1" type="text" id="Repeater1_txtbox1_0"></td>
<input type="hidden= name="Repeater1$ctl100$HiddenField1" id="Repeater1_HiddenField1_0">


</tr>
Avatar billede anri Novice
10. oktober 2013 - 14:11 #41
Ok.  Det ser ikke ud til at vi får sat attributter korrekt op.
Hvis du sætter et breakpoint inde i Repeater1_ItemDataBound, kommer du så derind, og kører den som den skal (for hver frugt)
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 14:22 #42
Det gør den ikke, den kommer til denne her linie

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            TextBox Textbox_antal = FindControl("txtbox1") as TextBox;
            if (Textbox_antal == null) return;

Også går den ud på Default2.aspx siden der hvor jeg har <%#Eval("frugt_navn")%>

også hopper den tilbage i codebehind og køre den samme linie og hopper tilbage på Default.aspx
Avatar billede anri Novice
10. oktober 2013 - 14:32 #43
Nååh.
I morges da jeg sendte dig det fulde eksempel, var en af linierne den her:
                TextBox Textbox_antal = e.Item.FindControl("TextBox1") as TextBox; //Her søgte du ikke efter control'en i e.Item og derfor fik du ikke fat i nogen TextBox og den exitede i næste linie

Læg mærke til at der står e.Item.FindControl
Findcontrol skal jo returnere din TextBox, ellers kan du ikke sætte attributter på den.  ..og husk nu at den skelner imellem store og små bogstaver
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 14:35 #44
så kommer denne her fejl

Unable to cast object of type 'System.Data.DataRowView' to type 'System.Data.DataRow

Line 77:            Textbox_antal.Attributes.Add("FrugtID", string.Format("{0}", ((DataRow)e.Item.DataItem)["frugt_id"])); //Læg en ny attribut på TextBoxen der peger på frugten
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 14:37 #45
skal den have en foreach evt?
Avatar billede anri Novice
10. oktober 2013 - 14:43 #46
Prøv at kigge lidt på den kode jeg postede i morges.
Der er kommentarer på den, og den virker efter hensigten.
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 15:16 #47
Tusind tak for hjælpen :-)
Avatar billede anri Novice
10. oktober 2013 - 15:37 #48
Velbekomme.
Jeg håber også du kan lære noget af fremfor at jeg bare spotter fejlene og retter dem for dig ;-)
Avatar billede tinaw25 Nybegynder
10. oktober 2013 - 16:20 #49
Jeg har lært at man kan bruge attributter, den mulighed var jeg slet ikke klar over. Så det skal jeg lige læse noget mere om. Var slet ikke klar over at man på den måde kunne bestemme tingende på
Avatar billede tinaw25 Nybegynder
16. oktober 2013 - 16:43 #50
Hej anri

Jeg sidder og kæmper med at få lagt ID med over i Session. Den skal laves som en variabel, men kan simpelthen ikke hitte ud af hvad den skal defineres som;

int frugtID = Attributes["ID"];????



string frugtNavn = Textbox_antal.Attributes["FrugtNavn"]; //Det her skal vel være en streng!?
                int enkeltFrugtVaerdi = int.Parse(Textbox_antal.Attributes["FrugtVaerdi"]);
                int enkeltFrugtAntal = int.Parse(Textbox_antal.Text);

             
Jeg håber du gider hjælpe mig, skal nok give dig point
Avatar billede anri Novice
16. oktober 2013 - 17:51 #51
int frugtID = int.parse(Textbox_antal.Attributes["ID"]);

Du skal lige læse lidt op på datatyper.  Man kan ikke bare smide en streng ind i en integer, eller for den sags skyld en generic list ind i en datatable (som du har et andet åbent spørgsmål på).
Man er nødt til lige at forholde sig til hvad man vil, og så vælge den datatype der passer bedste ind i scenariet, og konvertere hvor det ikke lige kan dækkes ind.
Avatar billede tinaw25 Nybegynder
16. oktober 2013 - 19:04 #52
Takker

Nej, fandt ud af det med generec list og fik dem konvateret til en datatable
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