0

I'm trying to make an app(for college) which shows two rectangles which represent a clock. I have two rectangles, one which respresents seconds and the other minutes. The width must be adjusted every second to correspond to the time.

public partial class MainWindow : Window
{
        Rectangle rectMinuut = new Rectangle();
        Rectangle rectSeconde = new Rectangle();
    public MainWindow()
    {
        InitializeComponent();

        rectMinuut.Stroke = new SolidColorBrush(Colors.Black);
        rectSeconde.Stroke = new SolidColorBrush(Colors.DarkBlue);
        rectSeconde.Fill = new SolidColorBrush(Colors.DarkBlue);
        rectMinuut.Fill = new SolidColorBrush(Colors.Black);
        rectSeconde.Height = 100;
        rectMinuut.Height = 100;
        var date = DateTime.Now;
        int widthMinute = date.Minute;
        int widthSecond = date.Second;
        rectMinuut.Width = widthMinute;
        rectSeconde.Width = widthSecond;
        Canvas.SetTop(rectMinuut, 50);
        Canvas.SetTop(rectSeconde, 150);
        paperCanvas.Children.Add(rectSeconde);
        paperCanvas.Children.Add(rectMinuut);

        Timer timer = new Timer();
        timer.Interval = (1000); 
        timer.Elapsed += new ElapsedEventHandler(timer_Tick);
        timer.Start();
    }
    private void timer_Tick(object sender, ElapsedEventArgs e)
    {
        //refresh here... 
        var date = DateTime.Now;
        int widthMinute = date.Minute;
        int widthSecond = date.Second;
        rectMinuut.Width = widthMinute;
        rectSeconde.Width = widthSecond;
    }
}}

I tried different options, but my application always crashes when assigning a new value to rectMinuut.Width in the timer_Tick method.

Edit: Correct answer:

using System.Windows.Threading;
public partial class MainWindow : Window
{
    private DispatcherTimer timer = new DispatcherTimer();
    public MainWindow()
    {
        InitializeComponent();
        timer.Interval = TimeSpan.FromMilliseconds(200); //200ms, because code takes time to execute too
        timer.Tick += timer_Tick;
        timer.Start();

    }
    private void timer_Tick(object sender, EventArgs e)
    {
        //refresh here... 

        Rectangle rectMinuut = new Rectangle();
        Rectangle rectSeconde = new Rectangle();
        rectMinuut.Stroke = new SolidColorBrush(Colors.Black);
        rectSeconde.Stroke = new SolidColorBrush(Colors.DarkBlue);
        rectSeconde.Fill = new SolidColorBrush(Colors.DarkBlue);
        rectMinuut.Fill = new SolidColorBrush(Colors.Black);
        rectSeconde.Height = 100;
        rectMinuut.Height = 100;
        var date = DateTime.Now;
        int widthMinute = date.Minute * 2; //increase/scale width
        int widthSecond = date.Second * 2;
        rectMinuut.Width = widthMinute;
        rectSeconde.Width = widthSecond;
        Canvas.SetTop(rectMinuut, 50);
        Canvas.SetTop(rectSeconde, 150);
        paperCanvas.Children.Add(rectSeconde);
        paperCanvas.Children.Add(rectMinuut);
    }
}

}

Fatih
  • 123
  • 1
  • 9
  • 1
    See [Updating GUI (WPF) using a different thread](http://stackoverflow.com/questions/4253088/updating-gui-wpf-using-a-different-thread) – C Perkins May 09 '17 at 15:56
  • 1
    Also see [Timer.Elapsed Event](https://msdn.microsoft.com/en-us/library/system.timers.timer.elapsed(v=vs.110).aspx). By default, the Elapsed event is called from the thread pool, but the UI cannot be updated directly from another thread. I imagine that an entire second should be enough time to complete one timer call for redrawing a simple rectangle, but depending on what your code will end up doing, you may need to pay attention to other threading details. – C Perkins May 09 '17 at 16:03
  • Thanks! I fixed it with threading and using DispatcherTimer. See edit for fixed code. – Fatih May 09 '17 at 18:21

0 Answers0