2

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)
bad_coder
  • 11,289
  • 20
  • 44
  • 72

1 Answers1

2

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

Brian Berns
  • 15,499
  • 2
  • 30
  • 40