for i lista - problem z kolejnością odczytu

0

Witajcie,

Piszę program w C# zliczający kliknięcia przycisków podpiętych pod Arduino.

Po kliknięciu pierwszego przycisku ma rozpocząć się zliczanie czasu, natomiast po kliknięciu drugiego przycisku ma się zatrzymać.

Może dojść do sytuacji, których ilość użycia pierwszego przycisku będzie większa niż drugiego.

Po wciśnięciu drugiego przycisku wyświetla się czas w labelu i wynik od pierwszego kliknięcia pierwszego przycisku do pierwszego kliknięcia drugiego przycisku przenoszony jest do listboxa.

Problem polega na tym, że nie mam pomysłu jak uporządkować kliknięcia. Aktualnie (kod poniżej) jeżeli kliknę kilka razy pierwszy przycisk i później kilka razy drugi, to wyświetla i przenosi do listboxa tylko wynik od ostatniego kliknięcia pierwszego przycisku.

  public void button5_Click(object sender, EventArgs e)
        {
            
            circularProgressBar1.Update();
            ilosc_klikniec++; 
            label1.Text = "" + ((ilosc_klikniec / 2) + ((ilosc_klikniecc / 2) * -1)); 

            for (m = 0; m < 1; m++)
            {
              
                    sws.Add(new Stopwatch());

                    sws[m].Start();
                
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            ilosc_klikniecc++;
            label5.Text = "" + ilosc_klikniecc/2 ;

            timer2.Enabled = true; 

            
              
                    sws[m].Stop();
                    this.label3.Text = string.Format("{0:mm\\:ss}", sws[m].Elapsed);

                    listBox1.Items.Add(string.Format("{0:mm\\:ss}", sws[m].Elapsed));

                    if (circularProgressBar1.Maximum < sws[m].ElapsedMilliseconds)
                    {
                        label3.ForeColor = System.Drawing.Color.Green;
                    }
                    else
                    {
                        label3.ForeColor = System.Drawing.Color.Red;
                    }
                
            
        }
0

Wątpię że rozumiem co chcesz zrobić, ale wydaje mi się że chcesz użyć kolejki

Pierwszy button wrzuca stopwatche #1 oraz #2, a drugi zrzuca najpierw #1, a następnie #2.

var q = new Queue<int>();

q.Enqueue(1);
q.Enqueue(2);

Console.WriteLine(q.Dequeue());
Console.WriteLine(q.Dequeue());
Console.WriteLine(q.Count); // 0
0

@1a2b3c4d5e:

Przepraszam, że tak nie ogarniam, ale cały czas myślę, że w przypadku mojego kodu (poniżej) elementem przechowującym wartości moich stopwatchy jest lista sws, dlatego do listy chciałem dodać kolejkę "k", która będzie przyporządkowywała kolejne stopwatche zgodnie z parametrem przypisanym do for - czyli "m" i drugi button bedzie je kolejno zrzucał.

tylko to nie działa - wyskakuje Argument "1": nie można przekonwertować z "void" na "int"


 public partial class Form1 : Form
    {

        private SerialPort Serport; //serial port
        string raz; // deklaracja zmiennej pierwszej arduino
        string dwa; //deklaracja zmiennej drugiej arduino
        public bool trzy = true; //deklaracja zmiennej boolean
        public static List<Stopwatch> sws = new List<Stopwatch>();
        public static Queue<int> k = new Queue<int>();
        private int ilosc_klikniec = 0; // zmienne do zliczania kliknięć przez arduino
        private int ilosc_klikniecc = 0;
        public bool wlacz2; // zmienne do arduino
        public bool wlacz1 = true;
        public bool wylacz1 = true;
        private delegate void setLabelTextDelegate(string text);
        public bool wylacz2 = true;
        public TimeSpan czas;
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
        private Form2 Form2; 
        private Form5 Form5;
        private Stream fileStream;
        int m;
    

        public void button5_Click(object sender, EventArgs e)
        {
            

            circularProgressBar1.Update();
            ilosc_klikniec++; // weryfikacja ilości kliknięć
            label1.Text = "" + ((ilosc_klikniec / 2) + ((ilosc_klikniecc / 2) * -1)); // konieczne dla poprawności odczytu z Arduino

            for (m = 0; m < 1; m++)
            {

              

                    sws.Add(new Stopwatch());

                    sws[k.Enqueue(m)].Start();

                
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            
            
            ilosc_klikniecc++;
            label5.Text = "" + ilosc_klikniecc/2 ;

            timer2.Enabled = true; // nie pamiętam po co to

            

                sws[k.Dequeue(m)].Stop();
                this.label3.Text = string.Format("{0:mm\\:ss}", sws[k.Dequeue(m)]);

                listBox1.Items.Add(string.Format("{0:mm\\:ss}", sws[k.Dequeue(m)]));

                if (circularProgressBar1.Maximum < sws[k.Dequeue(m)])
                {
                    label3.ForeColor = System.Drawing.Color.Green;
                }
                else
                {
                    label3.ForeColor = System.Drawing.Color.Red;
                }
            
            
        }
       
0

Bardziej myślałem o czymś takim

image

private Queue<Stopwatch> queue = new Queue<Stopwatch>();

public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    var sw = new Stopwatch();
    sw.Start();

    queue.Enqueue(sw);
}

private void button2_Click(object sender, EventArgs e)
{
    if (queue.Count > 0)
    {
        var sw = queue.Dequeue();
        sw.Stop();
        richTextBox1.Text += sw.Elapsed.TotalSeconds + Environment.NewLine;
    }
}
0

@1a2b3c4d5e: działa idealnie po małej modyfikacji dzięki :D !

Jednak dołożę łyżeczkę dziegciu, otóż komplementarnym elementem programu jest progressbar, który odlicza czas do końca zdarzenia.

Jeżeli zdarzenie wydarzy się przed upłynięciem czasu progressbara, ten powinien aktualizować się do kolejnego czasu (nie resetować, tylko ustalić wartość na poziomie pozostałego czasu dla kolejnego zdarzenia, ponieważ button1 można wcisnąć kilka razy przed wciśnięciem buttona2, dlatego tworzy się kolejka)

Kombinowałem za Twoim przykładem z kolejką, jednak wyrzuca mi błąd chwilę po uruchomieniu programu:

"System.ArgumentOutOfRangeException: „Wartość '-1' nie jest prawidłową wartością dla 'Value'. Wartość 'Value' powinna znajdować się w zakresie od 'minimum' do 'maximum'.
Nazwa parametru: Value”"

 public void button5_Click(object sender, EventArgs e)
        {
            
           
            ilosc_klikniec++; // weryfikacja ilości kliknięć
            klik++;
            label1.Text = "" + ((ilosc_klikniec / 2) + ((ilosc_klikniecc / 2) * -1)); // konieczne dla poprawności odczytu z Arduino

            if (klik == 2) // musi być dwa ponieważ przycisk w arduino wyzwala double click i wykonywało duplikację
            {
                var sw = new Stopwatch();
                

                sw.Start();

                queue.Enqueue(sw);
                

                {
                    Thread.Sleep(300); //reset wartości inta dla klik
                    klik = 0;
                }

            
                var swa = new TimeSpan(czas.Hours, czas.Minutes, czas.Seconds - 1);
                queue1.Enqueue(swa);

                circularProgressBar1.Value = swa.Minutes * 60 + swa.Seconds;
            }
        }

        public void button6_Click(object sender, EventArgs e)
        {
            
            ilosc_klikniecc++;
            klik2++;
            label5.Text = "" + ilosc_klikniecc/2 ;

            timer2.Enabled = true; 

            if (klik2 == 2) // musi być dwa ponieważ przycisk w arduino wyzwala double click i wykonywało duplikację
            {
                var sw = queue.Dequeue();
                var swa = queue1.Dequeue();


                circularProgressBar1.Value = swa.Minutes * 60 + swa.Seconds;

                circularProgressBar1.Update();

                sw.Stop();
                        this.label3.Text = string.Format("{0:mm\\:ss}", sw.Elapsed);
                        listBox1.Items.Add(string.Format("{0:mm\\:ss}", sw.Elapsed));
                        if (circularProgressBar1.Maximum > sw.Elapsed.TotalSeconds)
                        {
                            label3.ForeColor = System.Drawing.Color.Green;
                        }
                        else
                        {
                            label3.ForeColor = System.Drawing.Color.Red;
                        }

                      
                {
                    Thread.Sleep(300); //reset wartości inta dla klik2
                    klik2 = 0;
                }

            }


        }

0

no ale w której linijce dostajesz ten błąd?

tutaj? circularProgressBar1.Value = swa.Minutes * 60 + swa.Seconds;?

no to pewnie za dużą wartość tam wrzucasz, sprawdź jaki jest min oraz max i zmień zakres lub przeskaluj.

0

@1a2b3c4d5e: Tak dokładnie w tym miejscu, jednak wartość nie może być za duża bo w błędzie wskazuje, że: "„Wartość '-1' nie jest prawidłową wartością dla 'Value'."

Myślę, że chodzi o zapis

var swa = new TimeSpan(czas.Hours, czas.Minutes, czas.Seconds - 1);

i wyrzuca ten błąd od razu po uruchomieniu programu, a nie po kliknięciu, co też jest dla mnie dziwne, że program bez wyzwolenia buttona wyrzuca ten błąd.

Czy jeżeli wcześniej w kodzie tzn. w innych voidach występuje polecenie circuralprogressbar1.update(); może mieć wpływ na to ?

0

Problem rozwiązany
brakowało kodu dla zmiennej czas

 public Form1()
        {
            InitializeComponent();
            timer.Tick += new EventHandler(Odliczanie); 
            timer.Interval = 1000;
            circularProgressBar1.Update();


        }
 

        private void Odliczanie(object sender, EventArgs e)
        {
            if (czas.TotalSeconds > 0) 
            {

                czas = new TimeSpan(czas.Hours, czas.Minutes, czas.Seconds - 1);
                WyswietlCzas();
                circularProgressBar1.Value = czas.Minutes * 60 + czas.Seconds;

                circularProgressBar1.Update();
            }
            else
            {
                timer.Stop();
                MessageBox.Show("Koniec czasu");
            }

Temat do zamknięcia

1 użytkowników online, w tym zalogowanych: 0, gości: 1