在覆盖onPaint方法F#的构造函数中定义的访问列表

时间:2014-01-08 18:08:40

标签: f#

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

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  

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

如果你确实想要使用主构造函数,那么就可以这样做,使用let绑定所有私有字段并为构造函数的代码进行绑定。所有非静态成员都可以访问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