Being new to F#, I'm trying to understand how to make graphic updates in a Form triggered by timer events.
My expectation was that the below simple routine should continue drawing new "random" lines every second.
Calling line() outside the timer event works seemingly without any problems, but I cannot get my head around why nothing gets displayed on the screen when the very same function is invoked via the timer event.
open System
open System.Drawing
open System.Windows.Forms
let form = new Form(Text="Simple Animation", Size=Size(400,500))
let pen = new Pen(Color.Red, 4.0f)
let random = new Random()
let line x =
let flexRight = random.Next(29,300)
form.Paint.Add (fun e -> e.Graphics.DrawLine(pen, 30, 30, 350, flexRight))
let timer=new Timer(Interval=1000, Enabled=true)
timer.Tick.Add(fun time -> line())
form.Show()
Application.Run(form)
Any help very much appreciated, Thanks.
The major problem with you code is that on each timer tick just another brand new
Paintevent handler is added to your form instead of invoking a single registeredOnPaintcallback that would perform the drawing.You may get rid of your
linefunction definition and register instead a singlePaintcallback asThen on each timer tick
Paintevent may be fired, for example, by invalidating the form. This may be achieved by changing timer's callback code toThe entire behaving as expected snippet is listed below:
UPDATE: as it came out the original intent was showing on the form the superposition of all subsequent drawn lines, I provide one of possible ways to accommodate such behavior with the help of GraphicsPath. Utilizing it would require the following changes to the snippet above:
before the line adding the form
Paintevent handler add the line creating the instance ofGraphicsPathlet gp = new System.Drawing.Drawing2D.GraphicsPath()change the
Paintevent handler toform.Paint.Add(fun e -> gp.AddLine(30,30,350,random.Next(29,300)) e.Graphics.DrawPath(pen, gp))