timmer i kolorowanie figur

0

Witam.
Piszę ponieważ mam problem z pokolorowaniem automatycznym figur. Problem mój zobrazuje na prostym przykładzie, który po wyjaśnieniu pozwoli mi zastosować zaproponowane rozwiązane we właściwym większym projekcie. Potrzebuje przycisku który jest połączeniem RepeatButton i ToggleButton. Przycisk ten po kliknięciu ma w ustalonym odstępie czasu kolorować figury. Ponowne klikniecie przycisku ma skutkować zaniechaniem czynności barwienia.

Do rozwiązania tego problemu postanowiłem wykorzystać Timer. Jednak liczne próby napisania poprawnego kodu kończyły się fiaskiem, problem pojawia się w funkcji Paint. Kompilator sygnalizuje mi, że inny wątek korzysta już z rectangle. Prosiłbym o naprowadzenie na rozwiązanie które pozwoli rozwiązać powyższy problem.

public partial class MainWindow : Window
    {
        private Timer timer;
        List<Rectangle> rectangles;
        bool pom;
        int howmuchpaint;
        
        public MainWindow()
        {
            InitializeComponent();
            timer = new Timer();
            rectangles = new List<Rectangle>();
            for (int i = 0; i < 100; i++)
            {                
                Rectangle rec = new Rectangle();
                rec.Height = 20;
                rec.Width = 20;
                rec.Fill = Brushes.Black;
                canvas.Children.Add(rec);
                Canvas.SetLeft(rec, i * 40);
                Canvas.SetTop(rec, 100);
                rectangles.Add(rec);
                howmuchpaint = 0;
            }
        }

        private void ToggleButton_Click(object sender, RoutedEventArgs e)
        {

            if (((ToggleButton)sender).IsChecked == true)
            {
                timer.Interval = 1000;
                timer.Elapsed += new ElapsedEventHandler(this.Paint);
                timer.Start();
            }
            else
            {
                timer.Stop();
                timer.Elapsed -= new ElapsedEventHandler(this.Paint);
            }
        }

        private void Paint(object sender, EventArgs e)
        {
            rectangles[howmuchpaint].Fill = Brushes.Red;
            howmuchpaint++;
        }
    } 
0

Nie rysuj w funkcji timera, tylko zmieniaj wartość jakiegoś bool'a. Jeśli timer wywołuje funkcje asynchronicznie to może zostać wywołana 2x w tym samym czasie i mamy problem.

0

nie pamiętam dokładnie ale jest StopWatch albo inna klasa, stworzona dla WF która działa z wątkiem UI i nie powoduje konfliktu wątku. Nie mam IDE i nie przypomnę sobie. Ale jest ta klasa w Toolboksie VisualStudio. Ewentualnie posłuż się BackgroundWorkerem. On na pewno ma synchronizację z wątkiem GUI

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