简体   繁体   English

F#GUI问题(将C#转换为F#)

[英]F# GUI question (translate C# into F#)

I am translating a C# project into F#. 我正在将C#项目转换为F#。 While the logic part is easy, I am confused with the GUI part: 虽然逻辑部分很简单,但我对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);
     ...
}
}

Problem: How to write above C# code in F#...Thanks 问题:如何在F#中编写以上C#代码...谢谢

Note that F# doesn't have any WinForms designer, so if you have some controls in the Form, you'll need to create them manually (alternatively you can design the form in C#, compile it and reference it from F#). 请注意,F#没有任何WinForms设计器,因此,如果Form中有一些控件,则需要手动创建它们(或者,您可以在C#中设计表单,对其进行编译并从F#中引用它)。 You could start with something like this: 您可以从以下内容开始:

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) 
      (* ... *) )

It uses a couple of interesting things: 它使用了一些有趣的东西:

  • You can specify some parameters such as Width and Height in the constructor when calling the base class constructor. 调用基类构造函数时,可以在构造函数中指定一些参数,例如WidthHeight
  • You need to use as this in the class declaration, so that you can refer to the class in the do code (which is run during construction) 您需要使用as this在类声明,这样你可以参考在类do代码(这是施工过程中运行)
  • You can use Add to register event handler and you can either give it a named function (eg patinGui ) or a lambda function if you need to do only some simple call (eg handling of Click ) 您可以使用Add来注册事件处理程序,如果只需要进行一些简单的调用(例如, Click处理),则可以给它命名函数(例如patinGui )或lambda函数。

Here's another example of using a form but this time with an outside 3D library called Mogre . 这是另一个使用表单的示例,但是这次使用的是外部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())

Here is the full code if you want to try running it. 如果您想尝试运行它,请参见以下完整代码。 You will need to download Mogre and reference the Mogre dll. 您将需要下载Mogre并引用Mogre dll。 Also since this code pulls resources out of the samples you have to set your projects working directory to "C:\\MogreSDK\\bin\\Debug" 同样,由于此代码从示例中提取资源,因此您必须将项目工作目录设置为“ 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM