F# Tip: Show a Form In Both Compiled and Interactive Mode
Lately I’ve FINALLY been getting back into some F# after a brief hiatus. I love the way that it keeps stretching my brain. Things have changed quite a bit with all of the slick new usability enhancements in the latest CTP. I need to dig out my data analysis scripts from the beginning of the year.
One of the first things I tried to make when I was learning F# was a simple “Hello World” Windows Forms application. Quickly you run into a problem — if you want to take advantage of the awesome “F# Interactive” window at the bottom of the screen, then after you have a form, you call .Show(). However, if you want the form to come up when the compiled application is executed, then you need to use Application.Run(). If we try to use Application.Run from within F# Interactive, we get the following error:
> let mainForm = new Form(Text=“Hello World”);;
val mainForm : Form
> Application.Run(mainForm);;
System.InvalidOperationException: Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead.
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at <StartupCode$FSI_0024>.$FSI_0024._main()
stopped due to error
Hmmm, we need a way to distinguish whether we are in compiled or interactive mode.
Thankfully the F# team has defined a number of compiler flags named COMPILED and INTERACTIVE that we can use. So we can have conditional code depending on the execution mode:
let showForm (f:Form) =
#if INTERACTIVE
f.Show()
#endif
#if COMPILED
Application.Run(f)
#endif
This works out well, since we can now just call showForm and not worry about what mode we’re in. For example, this uber-simple Hello World WinForms application can be written as:
#light
open System.Windows.Forms;;
let showForm (f:Form) =
#if INTERACTIVE
f.Show()
#endif
#if COMPILED
Application.Run(f)
#endif
let makeNewForm title =
let f = new Form()
f.Text <- title
f
let mainForm = makeNewForm “Hello World”
showForm mainForm
// Or:
//”Hello World” |> makeNewForm |> showForm
Then, to run it in F# Interactive, just hit Ctrl-A (select all) and Alt-Enter (run selection in the F# Interactive Window). Bam! Similarly, to run it in compiled mode we just punch F5.
Hope that helps!
This won’t be the last F# post, trust me.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
November 3rd, 2008 at 3:26 pm
[...] F# Tip: Show a Form In Both Compiled and Interactive Mode [...]