F# WPF Attributes have been ignored in this construct

151 views Asked by At

So. I was following along some tutorials on using WPF with F# blog here. I am working with the second one.

Since I am trying to learn F# WPF for larger more enterprise applications, it doesn't make much sense for me to use a bunch of F# script files. So I tried to convert it a regular .fs file as a type that I could create an instance of in a main method elsewhere.

namespace wpf
   module File1 =

       open System
       open System.Windows
       open System.Windows.Input
       type handleEvent ()=
           (* From Chap 1 - HandleAnEvent.cs *)
           let WindowOnMouseDown sender (args:MouseButtonEventArgs) =
              let win = unbox<Window> sender
              let str = String.Format("Window clicked with {0} button at point ({1})",args.ChangedButton,args.GetPosition(win))
              MessageBox.Show(str)|>ignore

           let win = new Window()
           [<STAThread()>]
           do 
               win.Title <- "Handle an Event"
               win.add_MouseDown(new MouseButtonEventHandler(WindowOnMouseDown))

               let app =  new Application() in
                app.Run(win) |> ignore

It looked like a pretty faithful recreation to me. I was able to take care of all that #r stuff by adding assembly references to the project. But now instead of a red error, I am getting a blue warning all over my do block that says:

Attributes have been ignored in this construct

When I googled that warning I came up empty handed so I thought I would get help here. I need that attribute to be able to properly run WPF I know it has something to do with the threads and without it, I will get this serious exception:

The calling thread must be STA, because many UI components require this

So what is my work around to apply the STA thread attribute to what is needed? Also, why is this construct invalid for STA in F#?

1

There are 1 answers

2
John Palmer On BEST ANSWER

The problem is that [<STAThread>] must go on a method - something like

[<STAThread()>]
let main() = 
   win.Title <- "Handle an Event"
   win.add_MouseDown(new MouseButtonEventHandler(WindowOnMouseDown))
   let app =  new Application() in
   app.Run(win) |> ignore

I anticipate that in your case it is not required to go in this file - you should just ensure that the topmost function (main or similar) is marked with STAThread.