f#timer event graphics.LineDraw不更新表单

时间:2018-01-15 03:35:08

标签: timer f# system.drawing.graphics

作为F#的新手,我正在尝试了解如何在由计时器事件触发的表单中进行图形更新。 我的期望是下面的简单程序应该每秒继续绘制新的“随机”线。 在计时器事件之外调用SELECT DISTINCT a.title_id, a.artist_id, fe_title.title, fe_artist.artist FROM fe_title_artist AS a INNER JOIN fe_title ON a.title_id = fe_title.id INNER JOIN fe_artist ON a.artist_id = fe_artist.id INNER JOIN fe_title_artist AS b WHERE a.title_id=b.title_id and b.artist_id=(SELECT id FROM fe_artist WHERE artist LIKE '%Patrick%') 似乎没有任何问题,但我无法理解为什么当通过计时器事件调用相同的函数时,屏幕上没有显示任何内容。

line()

非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:4)

代码的主要问题是,在每个计时器上,只有另一个全新的 Paint事件处理程序添加到您的表单而不是调用单个注册的OnPaint回调这将执行绘图。

您可以删除line函数定义并注册一个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()

UPDATE:因为它出现了原始意图在表单上显示所有后续绘制线的叠加,我提供了一种在{{3}的帮助下适应此类行为的可能方法}。利用它需要对上面的代码段进行以下更改:

  • 在添加表单Paint事件处理程序的行之前添加创建GraphicsPath

    实例的行

    let gp = new System.Drawing.Drawing2D.GraphicsPath()

  • Paint事件处理程序更改为

    form.Paint.Add(fun e -> gp.AddLine(30,30,350,random.Next(29,300)) e.Graphics.DrawPath(pen, gp))