FolderBrowserDialog not opening in fsharp script

92 views Asked by At

I am having a simple script to select a folder, the process is not responding on call to ShowDialog(), below is script file, runtime config file and cli command to run, I think I’m missing something, or my understanding is wrong,

test.fsx

#I @"C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\6.0.10\ref\net6.0" 
#r "System.Windows.Forms"

open System
open System.Windows.Forms

let folderPath = new Label()
let button = new Button(Text = "Select Folder")
let ini_dir = @"C:\Users\hayeskev\source\Workspaces"

let openFolderHandler = 
    EventHandler(fun _ _ ->
        let folderDlg = new FolderBrowserDialog()
        folderDlg.InitialDirectory <- ini_dir
        folderDlg.ShowNewFolderButton <- true
        let dlgResult = folderDlg.ShowDialog()
        if dlgResult.Equals(DialogResult.OK) then 
            folderPath.Text <- folderDlg.SelectedPath
        else
            folderPath.Text <- "Error")

button.Click.AddHandler(openFolderHandler)

let layout = new FlowLayoutPanel(Dock=DockStyle.Fill)
layout.Controls.Add(button)
layout.Controls.Add(folderPath)
let form = new Form()
form.Controls.Add(layout)
form.ShowDialog()

C:\Program Files\dotnet\sdk\6.0.402\FSharp\fsi.runtimeconfig.json

{
  "runtimeOptions": {
    "tfm": "net6.0",
    "frameworks": [
      {
        "name": "Microsoft.NETCore.App",
        "version": "6.0.10"
      },
      {
        "name": "Microsoft.WindowsDesktop.App",
        "version": "6.0.10"
      }
    ],
    "configProperties": {
      "System.Reflection.Metadata.MetadataUpdater.IsSupported": false
    }
  }
}

running using dotnet fsi test.fsx

also tried it with sta thread attribute

[<STAThread>]
do 
    Application.EnableVisualStyles()
    Application.SetCompatibleTextRenderingDefault(false)
    use form  = new MainGuiForm()
    Application.Run(form)
1

There are 1 answers

3
Brian Berns On

I reproduced this using a regular F# project and got the same behavior. To fix it, I had to call AddHandler on the STA thread. So my working code is:

open System
open System.Windows.Forms

let folderPath = new Label()
let button = new Button(Text = "Select Folder")
let ini_dir = @"C:\Users\hayeskev\source\Workspaces"

let openFolderHandler = 
    EventHandler(fun _ _ ->
        let folderDlg = new FolderBrowserDialog()
        folderDlg.InitialDirectory <- ini_dir
        folderDlg.ShowNewFolderButton <- true
        let dlgResult = folderDlg.ShowDialog()
        if dlgResult.Equals(DialogResult.OK) then 
            folderPath.Text <- folderDlg.SelectedPath
        else
            folderPath.Text <- "Error")

[<STAThread>]
button.Click.AddHandler(openFolderHandler)   // IMPORTANT: Must follow <STAThread>
let layout = new FlowLayoutPanel(Dock=DockStyle.Fill)
layout.Controls.Add(button)
layout.Controls.Add(folderPath)
let form = new Form()
form.Controls.Add(layout)
form.ShowDialog() |> ignore

Result looks like:

enter image description here

Related Questions in F#