6

I looked for a solution to this problem for a long time without success.

I am porting some of my C# code to F# and I am struggling with a Dispatcher.Invoke for a WPF element. Since I am a total noob in F#, the only thing that I am sure of is that the problem is located between the chair and the keyboard.

Here is my C# code:

foreach (var k  in ChartList.Keys)            
        {
            ChartList[k].Dispatcher.Invoke(
              System.Windows.Threading.DispatcherPriority.Normal,
              new Action(
                delegate()
                {
                    ChartList[k].Width = area.Width / totalColsForm;
                    ChartList[k].Height = area.Height / totalRowsForm;
                    ChartList[k].Left = area.X + ChartList[k].Width * currentCol;
                    ChartList[k].Top = area.Y + ChartList[k].Height * currentRow;
                    ChartList[k].doShow();
                }
            ));
         }

The part I am struggling with is the new Action(delegate() ... ). The compiler did not like any of my attempts to translate it.

What would be the translation of this snippet in F#?

Jack P.
  • 11,487
  • 1
  • 29
  • 34
Anass
  • 73
  • 4
  • What did you attempt? I'd expect `fun () -> ...` or `Action(fun () -> ...)` to work. – Daniel Mar 05 '13 at 15:51
  • @Daniel, exactly I tried both without success. I got the error "No overloads match for method 'Invoke'" => it is the translation of the delegate method that is the problem – Anass Mar 05 '13 at 16:18

1 Answers1

6

The Invoke method has a couple of overloads, so if you have something not exactly right inside the action, you might have some weird errors because the type checker won't know which overload to call. I just tried this and it worked fine:

open System
open System.Windows.Controls
open System.Windows.Threading

let b = Button()
b.Dispatcher.Invoke(
    DispatcherPriority.Normal,
    Action(fun () -> 
        b.Content <- "foo"
    )) |> ignore
Gustavo Guerra
  • 5,319
  • 24
  • 42
  • Thx Gustavo , I tried your code but I still have the same error I got earlier which is "Invalid use of an Interface type" while the term Action was underlined. I came up with a solution of my own. I declared explicitly type my_delegate = delegate of unit -> unit and the my code became for k in ChartList.Keys do ChartList.[k].Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new my_delegate(fun () -> ChartList.[k].doShow() )) |> ignore the code compiled but I still I don't understand why the use of Action raise errors – Anass Mar 05 '13 at 17:00
  • Do you happen to have any interface named Action? Try spelling out System.Action – Gustavo Guerra Mar 05 '13 at 17:06
  • It worked!! thanks Gustavo but I don't understand I have all the references needed with the open statements needed as well. odd! – Anass Mar 05 '13 at 17:13
  • 1
    try putting back Action and hovering over it to see the full name of the type. Probably there's something else named Action in your project, maybe some component of the charts library you're using and you happen to open after you open System – Gustavo Guerra Mar 05 '13 at 17:15