2014-01-08 83 views
2

我想用正方形对象列表在窗体上绘制正方形。在窗体上绘制正方形

let listOfSquares = ResizeArray() 

type square(x : float, y : float) = 
    let x = x 
    let y = y 
    let length = 50 
    let height = 50 

我使用下拉菜单来创建上点击一个正方形,然后我还有一个菜单按钮,无效的形式

let square = create.DropDownItems.Add("Square") 
let invalidate = file.DropDownItems.Add("Invalidate") 
square.Click.Add(fun _ -> listOfSquares.Add(new square(50.0, 50.0))) 
invalidate.Click.Add(fun _ -> form.Invalidate()) 

我遇到的问题是,OnPaint方法不画正方形,但每次你点击菜单按钮的方块都会添加到列表中。

override form.OnPaint e = 
    let g = e.Graphics 
    for square in listOfSquares do 
    g.FillRectangle(Brushes.Aqua, 300, 150, 48, 48); 

我试图手动值添加到列表中,然后运行像下面

override form.OnPaint e = 
    listOfSquares.Add(50,50) 

    let g = e.Graphics 
    for square in listOfSquares do 
    g.FillRectangle(Brushes.Aqua, 300, 150, 48, 48); 

其中一期工程,我相信这个问题是在form.invalidate的程序,但即时通讯相当新的F#我无法找到问题。

+1

在这段代码中,你实际上从来没有在循环中使用'square'。 –

+0

此外,你应该缩进你的for循环的正文('g.fillrectangle'应该缩进四个空格) –

回答

2

首先,您需要添加一种方法来从您的方形类型中拉出属性。我个人只使用这里记录:

type Square = { X : int; Y : int; Length : int; Height: int } 

有了这个,你点击处理程序将需要:

square.Click.Add(fun _ -> listOfSquares.Add({ X = 50; Y = 50 ; Width = 50; Height = 50))) 

OnPaint方法需要实际绘制正方形:

override form.OnPaint e = 
    let g = e.Graphics 
    for square in listOfSquares do 
    g.FillRectangle(Brushes.Aqua, square.X, square.Y, square.Length, square.Height); 

请注意,这将在同一位置添加所有方块,因此它们将被堆叠。当然,您会想要更改逻辑,以便每次都将其置于唯一的位置(更改X和Y)。


编辑:

经过进一步调查,这个问题实际上是,有一个额外的让错误的范围,这是导致事件处理程序添加到错误集合listOfSquares结合。这意味着OnPaint覆盖与事件处理程序的不同ResizeArray有效。

+0

这个OnPaint仍然doesent画,当我点击square.Click并使其无效。之前我已经尝试刷新,但它确实有所作为。 – Bobson

+0

@ user2165793如果你在那里放置一个断点,它会被击中吗? –

+0

它确实在listOfSquares中为正方形而行,但不是g.FillRectangle(Brushes.Aqua,square.X,square.Y,square.Length,square.Height) – Bobson