I am translating a C# project into F#. While the logic part is easy, I am confused with the GUI part:
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
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#). 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:
Width
and Height
in the constructor when calling the base class constructor. as this
in the class declaration, so that you can refer to the class in the do
code (which is run during construction) 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
) Here's another example of using a form but this time with an outside 3D library called 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. Also since this code pulls resources out of the samples you have to set your projects working directory to "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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.