简体   繁体   English

看到C#windows形成来自F#的项目代码

[英]seeing C# windows forms project code from F#

I have a C# Windows Forms project open with some C# code in it. 我有一个C#Windows窗体项目,其中包含一些C#代码。

Question: How can I have an F# file that I can write F# code in but still referencing all the C# code I have on Form1.cs (including the GUI). 问题:我如何拥有一个F#文件,我可以编写F#代码,但仍然引用我在Form1.cs上的所有C#代码(包括GUI)。

I can successfully do this: 我可以成功地做到这一点:
- Create a C# Windows Forms project - 创建C#Windows窗体项目
- Create a F# Library project - 创建一个F#Library项目
- Reference the F# Library DLL from my C# project - 从我的C#项目中引用F#Library DLL
- That way I can call F# functions from C# - 这样我可以从C#调用F#函数

But I still can't see my buttons and textboxes from F# 但我还是看不到来自F#的按钮和文本框
I understand that that is because it's a library and it can't reference System.Windows.Forms 我理解那是因为它是一个库,它不能引用System.Windows.Forms

So how do I fix this? 那么我该如何解决这个问题呢? I don't want it to be a library or this or that, I just want it to be a file that will allow me to write F# code while being able to reference my C# Form and code. 我不希望它是一个库或者这个或那个,我只是希望它是一个允许我编写F#代码的文件,同时能够引用我的C#表单和代码。

I guess you can say I want an F# file that is also a "partial class Form1" so that I can continue writing code for the same Project, but using F# instead. 我想你可以说我想要一个F#文件,它也是一个“部分类Form1”,这样我就可以继续为同一个Project编写代码,但是使用F#代替。 How do I do that? 我怎么做?

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#. 如果我正确理解了这个问题,你实际上是在询问如何构建你的应用程序,以便你可以使用WinForms设计器(仅在C#/ VB中可用)来创建表单,同时在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). 首先,有没有办法在一个单一的项目,这意味着你不能写东西就像一个混合两种语言partial用在C#F#和其他部分一个部分类(这在技术上几乎是不可能的)。 So, the only option is to write an F# project and a C# project and reference one from the other. 因此,唯一的选择是编写一个F#项目和一个C#项目,并引用另一个项目。 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. 从F#应用程序引用C#库:一种选择是在C#中创建一个简单的WinForms库项目,以包含使用WinForms设计器创建的表单(可能还有其他控件等),而不是其他任何内容。 Then you'd reference this library from an application created in F# and implement all the user interaction in the F# application. 然后,您将从在F#中创建的应用程序引用此库,并在F#应用程序中实现所有用户交互。

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. 如果确保将WinForms设计器创建的YourForm类以及添加到表单中的所有相关控件标记为public ,则可以引用该表单并从F#应用程序控制它。

  • 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") 我在本书的一个示例中使用了这种方法,所以如果您正在寻找一个示例,您可以查看第14章的源代码 (查找“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. 从C#应用程序引用F#库:以这种方式构建应用程序时,您需要创建一个F#库,它公开应用程序所需的所有基本功能,然后从C#应用程序引用它。 The C# application would add all the user-interface interaction code and it would call the F# library to preform the actual work. C#应用程序将添加所有用户界面交互代码,它将调用F#库来执行实际工作。

In this scenario, the F# library doesn't know anything about the C# form. 在这种情况下,F#库对C#表单一无所知。 If you reference System.Windows.Forms from your F# library then it may take some WinForms controls as arguments (eg to configure them & load data), but it won't know anything about the controls declared in C#. 如果从F#库引用System.Windows.Forms ,则可能需要一些WinForms控件作为参数(例如,配置它们和加载数据),但它不会知道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. 这种方法的一个可能的扩展是在F#库中声明一个接口,在C#应用程序中实现它,然后将一个实现传递回F#库。 The interface may expose some important properties of the application (eg give access to all the important WinForms controls). 该接口可能会暴露应用程序的一些重要属性(例如,允许访问所有重要的WinForms控件)。 Once you give an implementation of the interface to your F# library, the F# library can use it to manipulate with the application. 一旦为F#库提供了接口的实现,F#库就可以使用它来操作应用程序。

(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) (带接口的方法需要编写更多代码,可能不太灵活,但如果你想用C#编写主应用程序并在那里声明表单,那么它可能是最好的选择)

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 . 您需要将对System.Windows.Forms.dll的引用添加到F#项目,并将Form1类及其成员的可见性设置为public

(Libraries can also reference System.Windows.Forms; that's what reusable control projects are) (库也可以引用System.Windows.Forms;这就是可重用的控件项目)

You'll also need some way to call the F# code in the first place; 你还需要一些方法来调用F#代码; you might want to make the F# project an EXE (that calls Application.Run ) and the C# project into a library. 您可能希望将F#项目设置为EXE(调用Application.Run )和C#项目到库中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM