F#GUI问题(将C#翻译成F#)
问题描述:
我正在将C#项目翻译成F#。虽然逻辑部分很容易,我很困惑与GUI部分:F#GUI问题(将C#翻译成F#)
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#代码...感谢
答
注意,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
),或者如果你需要做的只是一些简单的调用(例如Click
处理)lambda函数
答
下面是一个使用形式的另一个例子,但这次与外部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并参考Mogre DLL。此外,由于该代码拉出来的资源,你必须设置你的项目的工作目录中的样本为“C:\ MogreSDK \ BIN \调试”
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()
如何写在F#此C#代码...谢谢。 – 2010-02-19 13:01:05