2014-01-08 29 views
0

我想重写onPaint方法,使其在构造函​​数中定义的两个列表中绘制对象,问题是我无法从重写的onPaint方法访问列表,I得到错误说当尝试使用listOfSquares或listOfCircles时列表或构造函数未定义。所以基本上,我如何从这个覆盖访问这些列表?重写onPaint方法在构造函数中定义的访问列表F#

type MainForm = class 
    inherit Form 

    val mutable g : Graphics // mutable means its not read-only 
    val mutable position : Point // position of the rectangle 

    new() as form = {g=null;position = new Point(0,0)} then 
    // double buffering 
    form.SetStyle (ControlStyles.UserPaint, true); 
    form.SetStyle (ControlStyles.DoubleBuffer, true); 
    form.SetStyle (ControlStyles.AllPaintingInWmPaint, true); 
    form.Width <- 900 
    form.Height <- 500 
    form.BackColor <- Color.White 
    form.Text <- "2D Graphics Editor"; 
    let listOfSquares = ResizeArray() 
    let listOfCircles = ResizeArray() 
    let menu = new MenuStrip() 

    let file = new ToolStripDropDownButton("File") // Menu 
    ignore(menu.Items.Add(file)) 


    let create = new ToolStripDropDownButton("Create") // Menu 
    ignore(menu.Items.Add(create)) 

    let square = create.DropDownItems.Add("Square") 
    let circle = create.DropDownItems.Add("Circle") 
    let newFile = file.DropDownItems.Add("New file") 
    let saveFile = file.DropDownItems.Add("Save file") 
    let openFile = file.DropDownItems.Add("Open file") 
    square.Click.Add(fun _ -> listOfSquares.Add(new square(5.0, 5.0)) |> ignore) 
    circle.Click.Add(fun _ -> listOfCircles.Add(new circle(10.0, 10.0)) |> ignore) 
    newFile.Click.Add(fun _ -> MessageBox.Show("newFile") |> ignore) 
    saveFile.Click.Add(fun _ -> MessageBox.Show("saveFile") |> ignore) 
    openFile.Click.Add(fun _ -> MessageBox.Show("openFile") |> ignore) 
    let dc c = (c :> Control) 
    form.Controls.AddRange([|dc menu|]); 


    // show the form 
    form.Show() 

    // override of paint event handler 
    override form.OnPaint e = 
     let g = e.Graphics in 
     // draw objects in listOfSquares and listOfCircles 

    end 

回答

1

如果你确实想使用一个主构造函数,那么你可以像这样做,使用让您所有的私有字段绑定和做的构造函数的代码绑定。所有非静态成员都可以访问let绑定。

请参阅F# documentation on classes以阅读有关此语法的内容。

type MainForm() as form = 
    inherit Form() 

    let mutable g : Graphics = null 
    let mutable position : Point = Point(0,0) 

    let listOfSquares = ResizeArray() 
    let listOfCircles = ResizeArray() 

    do 
     form.SetStyle (ControlStyles.UserPaint, true); 

     // ... your other initialization code 

     // show the form 
     form.Show() 

    override form.OnPaint e = 
     let g = e.Graphics 
     // draw objects in listOfSquares and listOfCircles 
+0

谢谢!按预期工作 – Jacco

1

您将其范围定义为构造函数而不是对象。将其声明上移到positiong已定义的位置。

我觉得这符合你的要求:

type test = 
    val mutable private temp:int 
    new() as this = {temp=5} then 
     this.temp <- 6 

重要的位是private访问修饰符,私营领域的使用{..}语法和使用this访问私有成员次级构造函数赋值。

这里是你的代码重写,以正确初始化列表:

type MainForm = 
    inherit Form 

    val mutable g : Graphics // mutable means its not read-only 
    val mutable position : Point // position of the rectangle 
    val listOfSquares : ResizeArray 
    val listOfCircles : ResizeArray 

    new() as form = {g=null;position = new Point(0,0)} then 
    // double buffering 
    form.SetStyle (ControlStyles.UserPaint, true); 
    form.SetStyle (ControlStyles.DoubleBuffer, true); 
    form.SetStyle (ControlStyles.AllPaintingInWmPaint, true); 
    form.Width <- 900 
    form.Height <- 500 
    form.BackColor <- Color.White 
    form.Text <- "2D Graphics Editor"; 
    listOfSquares <- ResizeArray() 
    listOfCircles <- ResizeArray() 
    let menu = new MenuStrip() 

    let file = new ToolStripDropDownButton("File") // Menu 
    ignore(menu.Items.Add(file)) 


    let create = new ToolStripDropDownButton("Create") // Menu 
    ignore(menu.Items.Add(create)) 

    let square = create.DropDownItems.Add("Square") 
    let circle = create.DropDownItems.Add("Circle") 
    let newFile = file.DropDownItems.Add("New file") 
    let saveFile = file.DropDownItems.Add("Save file") 
    let openFile = file.DropDownItems.Add("Open file") 
    square.Click.Add(fun _ -> listOfSquares.Add(new square(5.0, 5.0)) |> ignore) 
    circle.Click.Add(fun _ -> listOfCircles.Add(new circle(10.0, 10.0)) |> ignore) 
    newFile.Click.Add(fun _ -> MessageBox.Show("newFile") |> ignore) 
    saveFile.Click.Add(fun _ -> MessageBox.Show("saveFile") |> ignore) 
    openFile.Click.Add(fun _ -> MessageBox.Show("openFile") |> ignore) 
    let dc c = (c :> Control) 
    form.Controls.AddRange([|dc menu|]); 


    // show the form 
    form.Show() 

    // override of paint event handler 
    override form.OnPaint e = 
     let g = e.Graphics in 
     // draw objects in listOfSquares and listOfCircles 

    end 

由于@leafgarland证明,如果你不需要使用辅助构造函数,然后使用主构造为更清洁的语法。

type test() = 
    let mutable temp = 6 

    ... 

    override form.OnPaint e = 
     let g = e.Graphics 
     printfn "%i" temp 
+0

这是我initian想法,但是这给了我这个错误“错误这个定义可以只在一个类型中使用与主构造函数” 所以基本上是唯一的地方它可以让我申报清单在构造函数中.. – Jacco

+0

你能准确地显示你如何设法定义它们吗? – mydogisbox

+0

与在代码中的不同位置上的方法相同,也试图将它们定义为空列表并将它们的值赋予它们或将它们分配给构造函数中的ResizeArray,但其中没有一个能够工作。 – Jacco

相关问题