Timer f#计时器事件图形.LineDraw不更新表单
作为F#的新手,我试图理解如何以计时器事件触发的形式进行图形更新。 我的期望是,下面的简单例程应该每秒继续绘制新的“随机”线。 在计时器事件之外调用Timer f#计时器事件图形.LineDraw不更新表单,timer,f#,system.drawing.graphics,Timer,F#,System.drawing.graphics,作为F#的新手,我试图理解如何以计时器事件触发的形式进行图形更新。 我的期望是,下面的简单例程应该每秒继续绘制新的“随机”线。 在计时器事件之外调用line()似乎没有任何问题,但我无法理解,当通过计时器事件调用相同的函数时,屏幕上为什么没有显示任何内容 open System open System.Drawing open System.Windows.Forms let form = new Form(Text="Simple Animation", Size=Size(400,500)
line()
似乎没有任何问题,但我无法理解,当通过计时器事件调用相同的函数时,屏幕上为什么没有显示任何内容
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)
非常感谢您的帮助。代码的主要问题是,在每个计时器上,只会向窗体添加一个全新的
Paint
事件处理程序,而不是调用一个执行绘图的注册OnPaint
回调
您可以去掉行
函数定义,注册一个Paint
回调函数作为
form.Paint.Add(fun e -> e.Graphics.DrawLine(pen, 30, 30, 350, random.Next(29,300)))
然后在每个计时器上勾选Paint
事件,例如,通过使窗体无效来触发。这可以通过将计时器的回调代码更改为
timer.Tick.Add(fun _ -> form.Invalidate())
下面列出了整个行为符合预期的代码段:
#r "System.Windows.Forms"
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()
form.Paint.Add(fun e -> e.Graphics.DrawLine(pen, 30, 30, 350, random.Next(29,300)))
let timer=new System.Windows.Forms.Timer(Interval=1000, Enabled=true)
timer.Tick.Add(fun _ -> form.Invalidate())
form.Show()
更新:原意是在表格上显示所有后续绘制的线条的叠加,我提供了一种可能的方法,以帮助适应此类行为。利用它需要对上面的代码段进行以下更改:
- 在添加表单
事件处理程序的行之前,添加创建Paint
GraphicsPath
let gp=new System.Drawing.Drawing2D.GraphicsPath()
- 将
绘制
事件处理程序更改为
form.Paint.Add(乐趣e->gp.AddLine(30,30350,random.Next(29300)) e、 Graphics.DrawPath(笔,gp))
绘图
。图形正是我想要的。再次感谢!