Avatar billede bmdk Nybegynder
28. august 2009 - 19:42 Der er 17 kommentarer og
1 løsning

While loop driller

Hey eksperter!

Jeg er i øjeblikket ved at skrive en "book-sæder-i-biograf" i C# (ASP.NET), men jeg har et lille problem med mine select og deselect seats funktioner.

For at give jer et bedre overblik har jeg taget et screenshot af, hvordan det ser ud på sitet:

http://www.bo-mortensen.dk/buttons.JPG

Som I kan se, så er alle de sæder der er røde, optagede og kan derfor ikke vælges. De grønne sæder er dem der er frie og kan vælges. De gule er dem jeg lige har valgt.

I får lige lidt kode at kigge på, så beskriver jeg problemet nedenunder.

// Liste med de valgte Seat objekter
private static List<Seat> selectedSeats = new List<Seat>();

// Eventhandler til at vælge/fravælge sæder ud fra knappens farve
public void button_evt(object sender, EventArgs e)
    {
        Button b = (Button)sender;

        if (b.BackColor != Color.Red) // The seat cant be taken
        {
            if (b.BackColor == Color.Yellow) // Deselect seat
            {
                b.BackColor = Color.Green;
                Deselect(b);
            }
            else
            {
                b.BackColor = Color.Yellow; // Select seat
                Select(b);
            }
        }
    }

// Metode til at fravælge(slette) Seat objekter i selectedSeats listen
private void Deselect(Button b)
    {
        int i = 0;
        bool found = false;
        while(!found && i < selectedSeats.Count)
        {
            int theSeatNumber = selectedSeats[i].SeatNumber;
            if (selectedSeats[i].SeatNumber == Convert.ToInt32(b.ID))
            {
                found = true;
                selectedSeats.RemoveAt(i);
            }
            else
            {
                Console.WriteLine("Fejl");
            }
        }
    }

// Metode til at tilføje det valgte Seat objekt til selectedSeats listen
    private void Select(Button b)
    {
        selectedSeats.Add(new Seat(Convert.ToInt32(b.ID), false));
    }

Problemet er, at når jeg vælger flere sæder, som på billedet - og jeg derefter fravælger et af dem, så står sitet bare og "venter", somom det while-loopet kører uendeligt. Vælger jeg derimod kun 1 sæde og derefter deselecter det, så fungerer det fint. Yderligere, hvis jeg vælger flere sæder og deselecter det første sæde jeg valgte, så bliver det også fravalgt.

Det vil altså sige, at mit while loop kun kigger på det første element i listen og hvis det ikke stemmer overens med det nummer knappen har, så failer det. Men hvorfor?

Håber jeg har beskrevet problemet godt nok, ellers må I lige sige til :)

På forhånd tak for hjælpen.

Mvh. Bo
Avatar billede bmdk Nybegynder
28. august 2009 - 19:43 #1
Skal til at på arbejde nu, så kan først teste evt. forslag senere i aften..
Avatar billede arne_v Ekspert
28. august 2009 - 20:34 #2
Mangler du ikke at inkrementere i inden i while løkken?
Avatar billede bmdk Nybegynder
28. august 2009 - 20:48 #3
hey arne_v,

tak for svaret :)

Du har ret, men det prøvede jeg også tidligere, men desværre samme resultat :(

Tale i op efter:

found = true;
selectedSeats.RemoveAt(i);
i++;

Men kan lige prøve igen når jeg kommer hjem på et tidspunkt ;) Synes ellers det burde virke lige efter bogen..
Avatar billede windcape Praktikant
28. august 2009 - 20:52 #4
Er det bare mig, eller har du gjort det på en utrolig besværlig måde?

Med brug af et custom button objekt, og lidt LINQ kræver det jo næsten intet kode!


// seatsPanel er et FlowPanel
private void reserveButton_Click(object sender, EventArgs e)
{
    var buttons  = seatsPanel.Controls.OfType<SeatButton>();
    var selected = buttons.Where(x => x.Selected);
   
    foreach(var button in selected)
    {
        button.Selected = false;
        button.Reserved = true;
    }
}



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace Cinema
{
    public class SeatButton : Button
    {
        private bool _reserved;
   
        public bool Reserved
        {
            get { return _reserved; }
            set
            {
                _reserved = value;
               
                this.BackColor = _reserved ? Color.Red : Color.Green; 
                this.ForeColor = Color.White;               
            }
        }
       
        private bool _selected;
   
        public bool Selected
        {
            get { return _selected; }
            set
            {
                _selected = value;
                this.BackColor = _selected ? Color.Yellow : Color.Green;
                this.ForeColor = _selected ? Color.Black : Color.White;                   
            }
        }

        public SeatButton()
        {
            this.BackColor = Color.Green;
            this.FlatStyle = FlatStyle.Flat;
            this.ForeColor = Color.White;
            this.Location  = new Point(3, 3);
            this.Size      = new Size(37, 23);
            this.FlatAppearance.BorderSize = 0;
            this.UseVisualStyleBackColor = false;
        }

        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
            this.Selected = true;
        }
    }
}
Avatar billede windcape Praktikant
28. august 2009 - 20:53 #5
Og en metode til at hente reservede sæder med:


public IEnumerable<SeatButton> GetReservedSeats()
{
    var buttons  = seatsPanel.Controls.OfType<SeatButton>();
   
    return buttons.Where(x => x.Reserved);                       
}
Avatar billede windcape Praktikant
28. august 2009 - 20:54 #6
Og en lille fejl, SeatButton.OnClick skal self. være


protected override void OnClick(EventArgs e)
{
    base.OnClick(e);
    this.Selected = !this.Selected;
}


Altså, sætte den til det modsatte :)
Avatar billede windcape Praktikant
28. august 2009 - 20:55 #7
Eller hvis man ikke vil kunne vælge reservede sæder:


        protected override void OnClick(EventArgs e)
        {
            base.OnClick(e);
           
            if(!Reserved)
            {
                this.Selected = !this.Selected;
            }
        }
Avatar billede arne_v Ekspert
28. august 2009 - 20:56 #8
Du skal nok tælle i op selvom du ikke kommer ind i if blokken.
Avatar billede windcape Praktikant
28. august 2009 - 20:57 #9
Derudover bør en ASP.NET løsning skrives i Javascript, med AJAX backend, for ikke at reloade hver eneste gang man trykker på en knap !

Men WinForms konceptet kan sagtens føres over. Men essencen er at definere sin egen knap type, for at undgå problemer, og så benytte smart-selects med LINQ.
Avatar billede bmdk Nybegynder
28. august 2009 - 21:47 #10
arne_v: det skal jeg nok højst sandsynligt ja ;) er ret sikker på det er derfor hehe. Tak for det!

clausjoergensen: jo, du har muligvis (du har sandsynligvis mere erfaring i C# end jeg har ser det ud til) ret i, at min løsning på problemet er lidt besværligt. Jeg vil helt klart prøve at lege med det du har postet (og tak for det :)) når jeg kommer fra job! Det ser umiddelbart lidt smartere ud.

Skriver senere, hvad jeg finder ud af. Indtil videre: tak skal I begge have for hjælpen!
Avatar billede bmdk Nybegynder
31. august 2009 - 15:57 #11
Det var rigtig nok hvad arne_v skrev, at jeg skulle tælle i op i min else sætning. Din løsning ser nu også fin ud, windscape :) Ved ikke.. hvem af jer vil have point?
Avatar billede arne_v Ekspert
01. september 2009 - 01:17 #12
vi kan jo dele

her er et svar fra mig
Avatar billede bmdk Nybegynder
01. september 2009 - 09:47 #13
Sagtens :) windscape, smider du et svar også?
Avatar billede arne_v Ekspert
13. september 2009 - 02:19 #14
windcape ?
Avatar billede arne_v Ekspert
14. oktober 2009 - 02:08 #15
?
Avatar billede bmdk Nybegynder
14. oktober 2009 - 02:23 #16
Hmm, han er vist gået under jorden ;) Skal jeg bare give dig points, arne?
Avatar billede arne_v Ekspert
14. oktober 2009 - 02:35 #17
Han er ikke helt gået under jorden.

Giv ham lige et par dage inden du opgiver ham.
Avatar billede bmdk Nybegynder
14. oktober 2009 - 02:41 #18
Will do :)
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