F # GUI вопрос (перевод C # на F #) - PullRequest
1 голос
/ 19 февраля 2010

Я перевожу проект C # на F #. Хотя логическая часть проста, меня смущает часть GUI:

public partial class GomokuGUI : Form {
    private void GomokuGUI_Load(object sender, EventArgs e)
    {
        this.Width = 500;
        this.Height = 550;
        ...
        this.Paint += new PaintEventHandler(GomokuGUI_Paint);
        Graphics gp = this.CreateGraphics();
        DrawChessbord(gp); 
    }

    private void GomokuGUI_Paint(object sender, PaintEventArgs e)
    {
        Graphics gp = e.Graphics;
        DrawChessbord(gp);
    }

    void DrawChessbord(Graphics gp)
    {
        float w, h;
        SolidBrush br = new SolidBrush(linecolor);
        Pen p = new Pen(br, frame);
        gp.DrawLine(p, 20, 45, this.Width - 25, 45);
  ...
    }

   private void Form1_Click(object sender, EventArgs e) {
          Graphics gp = this.CreateGraphics();
                DrawChess(gp);
     ...
}
}

Проблема: Как написать код C # выше на F # ... Спасибо

Ответы [ 2 ]

5 голосов
/ 19 февраля 2010

Обратите внимание, что F # не имеет никакого дизайнера WinForms, поэтому если у вас есть некоторые элементы управления в форме, вам нужно будет создать их вручную (в качестве альтернативы вы можете создать форму в C #, скомпилировать ее и ссылаться на нее из F #) , Вы могли бы начать с чего-то вроде этого:

type GomokuGUI() as this =
  inherit Form(Width = 300, Height = 550)

  let DrawChessbord (gp:Graphics) =
    let br = new SolidBrush(linecolor)
    let p = new Pen(br, frame)
    gp.DrawLine(p, 20, 45, this.Width - 25, 45)
    // ...

  let paintGui (e:PaintEventArgs) =
    let gp = e.Graphics
    DrawChessbord(gp)

  do 
    this.Paint.Add(paintGui)
    this.Click.Add(fun _ ->
      let gp = this.CreateGraphics()
      DrawChess(gp) 
      (* ... *) )

Он использует пару интересных вещей:

  • Вы можете указать некоторые параметры, такие как Width и Height в конструкторе при вызове конструктора базового класса.
  • Вам необходимо использовать as this в объявлении класса, чтобы вы могли ссылаться на класс в коде do (который запускается во время построения)
  • Вы можете использовать Add для регистрации обработчика событий, и вы можете назначить ему именованную функцию (например, patinGui) или лямбда-функцию, если вам нужно сделать только какой-то простой вызов (например, обработка Click)
1 голос
/ 19 февраля 2010

Вот еще один пример использования формы, но на этот раз с внешней библиотекой 3D под названием Mogre .

type MogreForm() as this =
    inherit Form()

    let mogrePanel = new System.Windows.Forms.Panel()

    // Between Suspend and Resume Layout is normal form Designer Code
    do  base.SuspendLayout()

        mogrePanel.Location <- new System.Drawing.Point(0, 0)
        mogrePanel.Name <- "mogrePanel"
        mogrePanel.Size <- new System.Drawing.Size(483, 375)
        mogrePanel.TabIndex <- 0

        base.AutoScaleDimensions <- new System.Drawing.SizeF(6.0f, 13.0f)
        base.AutoScaleMode <- System.Windows.Forms.AutoScaleMode.Font
        base.ClientSize <- new System.Drawing.Size(483, 375)
        base.Controls.Add(mogrePanel)
        base.Name <- "MogreForm"
        base.Text <- "Simple F# Mogre Form";

        base.ResumeLayout(false)

        let mogreWin = new OgreWindow(Point(100, 30), mogrePanel.Handle)
        this.Disposed.Add(fun _ -> mogreWin.Dispose())
        this.Paint.Add(fun _ -> mogreWin.Paint())

Вот полный код, если вы хотите попробовать запустить его. Вам нужно будет загрузить Mogre и ссылаться на dll Mogre. Кроме того, так как этот код извлекает ресурсы из примеров, вы должны установить рабочий каталог ваших проектов в "C: \ MogreSDK \ bin \ Debug"

open System
open System.Windows.Forms
open System.Drawing

open Mogre

type OgreWindow(origin, hWnd) =
    //----------------------------------------------------- 
    // 1 enter ogre 
    //----------------------------------------------------- 
    let root = new Root()

    do  //----------------------------------------------------- 
        // 2 configure resource paths
        //----------------------------------------------------- 
        let cf = new ConfigFile()
        cf.Load("resources.cfg", "\t:=", true)

        // Go through all sections & settings in the file
        let seci = cf.GetSectionIterator()

        // Normally we would use the foreach syntax, which enumerates the values, but in this case we need CurrentKey too;
        while seci.MoveNext() do
            for pair in seci.Current do
                ResourceGroupManager.Singleton.AddResourceLocation(pair.Value, pair.Key, seci.CurrentKey)

        //----------------------------------------------------- 
        // 3 Configures the application and creates the window
        //----------------------------------------------------- 
        root.RenderSystem <- root.GetAvailableRenderers() |> Seq.find (fun rs -> rs.Name = "Direct3D9 Rendering Subsystem")
        root.RenderSystem.SetConfigOption("Full Screen", "No")
        root.RenderSystem.SetConfigOption("Video Mode", "640 x 480 @ 32-bit colour")

        root.Initialise(false) |> ignore
        let misc = new NameValuePairList()
        misc.["externalWindowHandle"] <- hWnd.ToString()
        let window = root.CreateRenderWindow("Simple Mogre Form Window", 0u, 0u, false, misc.ReadOnlyInstance)
        ResourceGroupManager.Singleton.InitialiseAllResourceGroups()

        //----------------------------------------------------- 
        // 4 Create the SceneManager
        // 
        //      ST_GENERIC = octree
        //      ST_EXTERIOR_CLOSE = simple terrain
        //      ST_EXTERIOR_FAR = nature terrain (depreciated)
        //      ST_EXTERIOR_REAL_FAR = paging landscape
        //      ST_INTERIOR = Quake3 BSP
        //----------------------------------------------------- 
        let sceneMgr = root.CreateSceneManager(SceneType.ST_GENERIC, "SceneMgr")
        sceneMgr.AmbientLight <- new ColourValue(0.5f, 0.5f, 0.5f)

        //----------------------------------------------------- 
        // 5 Create the camera 
        //----------------------------------------------------- 
        let camera = sceneMgr.CreateCamera("SimpleCamera")
        camera.Position <- new Vector3(0.0f, 0.0f, 100.0f)
        // Look back along -Z
        camera.LookAt(new Vector3(0.0f, 0.0f, -300.0f))
        camera.NearClipDistance <- 5.0f

        let viewport = window.AddViewport(camera)
        viewport.BackgroundColour <- new ColourValue(0.0f, 0.0f, 0.0f, 1.0f)

        let ent = sceneMgr.CreateEntity("ogre", "ogrehead.mesh")
        let node = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode")
        node.AttachObject(ent)

    member this.Paint() =
        root.RenderOneFrame() |> ignore

    member this.Dispose() =
        if root <> null then
            root.Dispose()

type MogreForm() as this =
    inherit Form()

    let mogrePanel = new System.Windows.Forms.Panel()

    // Between Suspend and Resume Layout is normal form Designer Code
    do  base.SuspendLayout()

        mogrePanel.Location <- new System.Drawing.Point(0, 0)
        mogrePanel.Name <- "mogrePanel"
        mogrePanel.Size <- new System.Drawing.Size(483, 375)
        mogrePanel.TabIndex <- 0

        base.AutoScaleDimensions <- new System.Drawing.SizeF(6.0f, 13.0f)
        base.AutoScaleMode <- System.Windows.Forms.AutoScaleMode.Font
        base.ClientSize <- new System.Drawing.Size(483, 375)
        base.Controls.Add(mogrePanel)
        base.Name <- "MogreForm"
        base.Text <- "Simple F# Mogre Form";

        base.ResumeLayout(false)

        let mogreWin = new OgreWindow(Point(100, 30), mogrePanel.Handle)
        this.Disposed.Add(fun _ -> mogreWin.Dispose())
        this.Paint.Add(fun _ -> mogreWin.Paint())

let main() =
    Application.EnableVisualStyles()
    Application.SetCompatibleTextRenderingDefault(false)
    Application.Run(new MogreForm())

[<STAThread>]
do main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...