tags:

views:

328

answers:

2
A: 

You need to add a reference to System.Windows.Forms.dll to the F# project, and set the visibility of the Form1 class and its members to public.

(Libraries can also reference System.Windows.Forms; that's what reusable control projects are)

You'll also need some way to call the F# code in the first place; you might want to make the F# project an EXE (that calls Application.Run) and the C# project into a library.

SLaks
Okay I added the reference to that dll by going to Add reference > .Net > System.Windows.Forms.Now I can do this on my F# file: open System.Windows.FormsNow how do I reference my Form1 functions and buttons etc?
Pessimist
Your F# code needs an instance of the `Form1` class. You might want to inherit it.
SLaks
I don't want to have the F# code being the executable and then C# being a library because the whole project is already in C#. I really just want to write F# code for the existing project and its controls and functions, which are all in C#.
Pessimist
Yes, but the C# project will need to give an instance to the F# code. The simplest way to do it is to keep all your code in C#, but invoke it from F#, supplying an inherited `Form1` instance. Otherwise, you'd have a circular reference.
SLaks
I'm not an OO guru but I don't see how inheriting would help. Can't I implement my F# code as being a partial class of Form1? Google says F# doesn't support partial classes but I don't know how outdated that is.
Pessimist
That is completely impossible (partial classes are merged at compile-time). You need to learn basic OO concepts.
SLaks
Well if I inherit my Form1 on my F# file wouldn't I be creating a new instance of the Form1 instead of adding code to it? I thought inheriting only went down, not up.
Pessimist
Yes; you need to run that inherited class instead of the original. Alternatively, you can pass the original instance of `Form1` to the F# project.
SLaks
Then it's not what I want to do. And you need to read up on criticisms of OOP. It's not the best paradigm for every problem (probably not for any). I'll give this a try but what I really wanted is kind of the opposite of inheriting (which in OOP parlance would be a partial class, but in normal speak would be simply "a file that can see my other files").
Pessimist
+6  A: 

If I understand the question correctly, you're actually asking how to structure your application so that you can use WinForms designer (which is only available in C#/VB) to create a form and at the same time, write the application logic in F#.

First of all, there is no way to mix the two languages in a single project, which means that you cannot write something like a partial class with one part in F# and other part in C# (this is technically almost impossible). So, the only option is to write an F# project and a C# project and reference one from the other. There are two ways to do this:

(Based on your answer and comments, I think you may prefer the first one)

Referencing C# library from F# application: One option is to create a simple WinForms library project in C# to contain the form (and possibly other controls etc.) created using the WinForms designer and nothing else. Then you'd reference this library from an application created in F# and implement all the user interaction in the F# application.

If you make sure to mark the YourForm class created by WinForms designer as well as all relevant controls added to the form as public, then you can reference the form and control it from your F# application.

  • I used this approach in the one sample in my book, so if you're looking for an example, you can look at the source code for Chapter 14 (look for "FSharpEffects")

Referencing F# library from C# application: When you structure your application in this way, you'll need to create an F# library that exposes all the basic functionality that your application needs and then reference it from a C# application. The C# application would add all the user-interface interaction code and it would call the F# library to preform the actual work.

In this scenario, the F# library doesn't know anything about the C# form. If you reference System.Windows.Forms from your F# library then it may take some WinForms controls as arguments (e.g. to configure them & load data), but it won't know anything about the controls declared in C#.

One possible extension to this approach is to declare an interface in the F# library, implement it in the C# application and then pass an implementation back to the F# library. The interface may expose some important properties of the application (e.g. give access to all the important WinForms controls). Once you give an implementation of the interface to your F# library, the F# library can use it to manipulate with the application.

(The approach with interface requires writing more code and may be less flexible, but if you want to write the main application in C# and declare the form there, it is probably the best option)

Tomas Petricek
First, I just bought your book yesterday and I like it a lot.Second, thank you and Manning for the free pdf copy after buying the paper version.I don't have .Net 4 yet so I can't compile your Chapter 14.In the meantime your reply is clear and detailed enough to answer my question.It's unfortunate that a class part C# and part F# is almost impossible. That's the kind of benefit that a Common Language Infrastructure should give us.Seeing that both C# and F# compile to the same Intermediate Language, I'd expect this not only to be possible but a given.
Pessimist
@Pessimist, in that case, I suggest you change your username ;)
Benjol
@Benjol: thanks for making me laugh :)I'm a pessimist not because I expect the worse (that's the "street" definition, glass half empty, etc, not real philosophy), but because I think that what exists now is bad. I'd say that's in line with what we just found out about C# and F#. ;)
Pessimist
@Pessimist - Since you can't have a partial class shared between multiple C# projects, I don't know why it would be a given that you could share a partial class between a C# and an F# project. I agree that it will be nice when F# projects have a better UI story (Silverlight, I'm looking at you) but let's not assume miracles here.
Joel Mueller