2014-01-08 2 views
0

Я хочу переопределить метод onPaint, чтобы он рисовал объекты в двух списках, определенных в конструкторе, проблема заключается в том, что я не могу получить доступ к спискам из переопределенного метода onPaint, I получить сообщение о том, что список или конструктор не определены при попытке использовать listOfSquares или listOfCircles. Итак, в основном, как мне получить доступ к этим спискам из этого переопределения?Списки доступа, определенные в конструкторе при переопределении onPaint method 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

Вы определили их область как конструктор, а не объект. Переместите свои объявления до position и g.

Я думаю, что это удовлетворяет ваши требования:

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 мысли, но это дает мне эту ошибку «Error Это определение может быть использовано только в типе с первичным конструктором» Так в основном единственным местом, где это позволяет мне объявлять списки находится в конструкторе .. – Jacco

+0

вы можете точно показать, как вы пытались их определить? – mydogisbox

+0

То же самое, что и сейчас, в другом месте в коде, также пытались определить их как пустые списки и дать им их значение или назначить их в ResizeArray в конструкторе, ни один из которых не работал. – Jacco

Смежные вопросы