Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF v4 feature works in compiled F# but not defined in F# Interactive

0.00/5 (No votes)
28 Feb 2012 1  
Mysterious problem in WPF v4, feature not defined.

WPFEventLoop in FSharp V4 with fsi.exe and WPF V4


While checking a compiled F# program to make sure it would execute in FSI (FSharp Interactive), I found that over 2000 lines of code had no errors or messages but 1 line of code referencing 'SelectionBrush' produced a 'not defined' error. After changing the '#I' and '#r' directives several times without effect, I decided I would paste the code into the F# REPL Window. Here is an abbreviated portion of the output:


----------------------------------------
    val Create : unit -> Compiler.Interactive.IEventLoop
    val Install : unit -> unit
  end
--> Added 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0' to the library include path
--> Referenced 'c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationcore.dl
--> Referenced 'c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\presentationframework.dll'
--> Referenced 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll'
--> Referenced 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Core.dll'
--> Referenced 'c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\WindowsBase.dll'
--> Referenced 'C:\Users\OWNER\SharpDevelop Projects\the Explorer Imperative\the Explorer Imperative\bin\Debug\Interop.IWshRuntimeLibrary.dll'
  textBox1.SelectionBrush <- Brushes.Black
  ---------^^^^^^^^^^^^^^
stdin(240,10): error FS0039: The field, constructor or member 'SelectionBrush' is not defined
>
---------------------------------------

Notice the 'Create' and 'Install' of the EventLoop. This is followed by the information that v4.0 was added to the Linrary Include path. This was followed by the information that it was still referencing v3.0 libraries.


Since this information was not output for the WPFEventLoop I deduced that loaded files did not produce that information so I pasted the code for the EventLoop into the REPL and sure enough, the Include Libraries were v3.0 (period->).


I did a quick check by commenting out the '#load' statement for the EventLoop and pasting the 2000 plus lines of code into the REPL. It compiled without errors but no WPF Event Loop. This meant that the only events the program could respond to were the events I had programmedevent handlers for(no typing).


The problem of WPF v4.0 Features not being defined in mysterious circumstances should not normally occur if you have the correct includes and referencesbut in this case the problem was hidden by the EventLoop being loaded from a separate file.


The Quick and Easy (and not even dirty) solution is to replace the v3.0include path with the v4.0 include path. On my computer it is this:


F#
//#I "c:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0";;
//#I "C:/WINDOWS/Microsoft.NET/Framework/v3.0/WPF/";;
#I @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
//#I @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF"

The first two lines are the original ones the last 2 are the new ones, of which only the first is required by the Event Loop but are probably required by something else in WPF v4.0.. The code below is the property of Microsoft Corporation and is included here to show the proper placement of the v4 include directive.


F#
#light

//-----------------------------------------------------------------------------
// A script utility for using WPF with F# Interactive (fsi.exe)
//
// Copyright (c) Microsoft Corporation 2005-2006.
// This sample code is provided "as is" without warranty of any kind. 
// We disclaim all warranties, either express or implied, including the 
// warranties of merchantability and fitness for a particular purpose. 
//-----------------------------------------------------------------------------

// #light
// When running inside fsi, this will install a WPF event loop
#if INTERACTIVE

//#I "c:/Program Files/Reference Assemblies/Microsoft/Framework/v3.0";;
//#I "C:/WINDOWS/Microsoft.NET/Framework/v3.0/WPF/";;
#I @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
//#I @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF"
#r "presentationcore.dll";;
#r "presentationframework.dll";;
#r "WindowsBase.dll";;

module WPFEventLoop = 
    open System
    open System.Windows
    open System.Windows.Threading
    open Microsoft.FSharp.Compiler.Interactive
    open Microsoft.FSharp.Compiler.Interactive.Settings
    type RunDelegate<'b> = delegate of unit -> 'b 
    
    let Create() = 
        let app  = 
            try 
                // Ensure the current application exists. This may fail, if it already does.
                let app = new Application() in 
                // Create a dummy window to act as the main window for the application.
                // Because we're in FSI we never want to clean this up.
                new Window() |> ignore; 
                app 
             with :? InvalidOperationException -> Application.Current
        let disp = app.Dispatcher
        let restart = ref false
        { new IEventLoop with
             member x.Run() =   
                 app.Run() |> ignore
                 !restart
             member x.Invoke(f) = 
                 try disp.Invoke(DispatcherPriority.Send,new RunDelegate<_>(fun () -> box(f ()))) |> unbox
                 with e -> eprintf "\n\n ERROR: %O\n" e; reraise()
             member x.ScheduleRestart() =   ()
                 //restart := true;
                 //app.Shutdown()
        } 
    let Install() = fsi.EventLoop <-  Create()
    
WPFEventLoop.Install();;

#endif

Keep your mind open, your mouth shut, and your computations closed!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here