我正在将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);
...
}
}
问题:如何在F#中编写上述C#代码...谢谢
答案 0 :(得分:5)
请注意,F#没有任何WinForms设计器,所以如果你在Form中有一些控件,你需要手动创建它们(或者你可以在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
)或lambda函数。 {1}})答案 1 :(得分:1)
以下是使用表单的另一个示例,但这次是使用名为Mogre的外部3D库。
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并参考Mogre dll。此外,由于此代码从示例中提取资源,您必须将项目工作目录设置为“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()