dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.07k stars 1.17k forks source link

Add F# support for WPF #162

Open hez2010 opened 5 years ago

hez2010 commented 5 years ago

Current there's no official F# support for WPF. xaml files were compiled to *.g.cs which can not be compiled with F# code together.

Please bring F# support to WPF, thanks!

JaggerJo commented 5 years ago

I am currently using the FsXaml type provide which works great for creating Windows, Controls, ...

a basic F# WPF template would be very useful

dotMorten commented 5 years ago

Based on decompiling the build tasks, I'm assuming it's "just" extending the MarkupCompiler that lives inside PresentationBuildTasks.dll and have it support outputting F# in addition to C# and VB. It would need to take a dependency on the FSharpCodeCompiler and all the language conditions inside for CSharp and VB extended to also take F# into account. There might be more to it - or that might be it. All 5 F# developers can then rejoice and go sing Kumbaya together :-)

cartermp commented 5 years ago

@dotMorten Please don't leave disrespectful/unhelpful comments like this:

All 5 F# developers can then rejoice and go sing Kumbaya together :-)

This doesn't get anyone anywhere.

dotMorten commented 5 years ago

Sorry to exaggerate - just trying to poke a little fun :-) I think for the most part my comment was quite constructive. But let's be honest: F# is a much smaller (albeit very vocal) community than C# and VB, so I assume it's been hard to justify the investment here. This is why open-sourcing WPF is such a big deal - the minorities that couldn't get things fixed because something was high-cost and only affected a small minority, now can submit PRs themselves to get these things addressed. To be clear: I fully support adding F# to WPF, as long as it doesn't jeopardize "the greater good" by taking resources away from more important things, which I think can be done judging from browsing the currently available reference source. Anyway let's get back on topic now 😋

thomasclaudiushuber commented 5 years ago

@dotMorten I did also code F# in some projects, so there are at least 6 of them. ;-) @cartermp I like F# and I've used in in different projects, but not in XAML projects yet. I didn't pick up the comment from @dotMorten as disrespectful, as it was just a bit of fun at the end of a a very solid and constructive comment. But anyway, thanks for chiming in, maybe others picked it up like that. Now, as Morten said, let's get back on topic.

What would it mean to bring in F# support:

AFAIK F# does not support partial classes. That's the way how C# brings the codebehind and the generated code from g.cs and g.i.cs together. That would mean that we would have to use something like type extensions in F# to bring in the generated code and combine it with the codebehind file. Or are there other ways in F# to bring in the generated code?

cartermp commented 5 years ago

There are two major avenues for F# support:

  1. Designer tooling that emits F# code
  2. Ability to work with Xaml files in an F# project

I think we should consider the first one out of scope. Generating F# code presents challenges that are different than the ones that already exist with C#, and the test matrix is enormous. The general host of issues that exist with design-time code generation will be compounded by adding another language into the mix.

The second avenue is already supported with FsXaml on .NET Framework today. The first actionable step is to work with @reedcopsey and others to move the project over to target .NET Core 3.0. After this works well enough, a template can be created with the .NET templating engine. Things can go from there.

dsyme commented 5 years ago

IMHO by far the most important value-add F# can bring to the WPF ecosystem is a code-oriented functional programming MVU framework similar to http://fsprojects.github.io/Fabulous.

Such a framework would

  1. be relatively cheap to make
  2. differentiated
  3. essentially impossible to do with C# (which is not sufficiently good at functional programming to be a good MVU language)
  4. well understood
  5. important (it allows WPF to compete with React/Redux) and
  6. Stockholm-syndrome-escaping

That's my 2c worth. We should do it, and there are already community efforts in that direction, see Elmish.WPF.

realvictorprm commented 5 years ago

Here's another F#er 😜 Sad to hear from other people that we're still such a minority.

I'm with @dsyme here, a Framework like Elmish for the F# Fable community in F# fully based on WPF would be awesome.

gerardtoconnor commented 5 years ago

@hez2010 Are you specifically looking for Xaml support or are you just interested in easily building type-checked UI? C# and XAML are a horrible marriage of code and xml due to the lack of C#'s composability, and the 100s of C# devs who need a html model to understand UI.

I might have been working on something for WPF for F# which you may find useful, something that does not involve XAML but only pure expressive F# code.

Kurren123 commented 5 years ago

F# user here, completely agree with @dsyme. I've been looking for an F# elmish for xaml for years but have yet to find a good solution. From my experience, MVU is a much more straightforward architecture than MVVM which is easier to test and reason about, and F# is the perfect fit.

hez2010 commented 5 years ago

@gerardtoconnor Actually I'm looking for Xaml support in F#, and I may not agree with your point. Xaml is a great tool which provides a method that allows non-programmers to design software UI. I think UI designing should not only be programmers' work, but it's also designers'. So it is necessary to bring xaml to F#. In wpf, desktop software development is like web development, and there're front-end and backend. Xaml is a frontend language just like html/css, and C# and F# are backend languages. I think it's an excellent design.

gerardtoconnor commented 5 years ago

@hez2010 That's fine if you like Xaml, and if you think it's great, I just know when I used to use it many years ago, wiring up behaviours via triggers, doing complex databinding etc in the Xaml was messy, clunky and verbose, even compared to C#, let alone F#. Intelisense and error checking was never as good as in code behind.

Although I generally agree with you on designers vs developers, I tend to find that having a designer code in Xaml, and a different dev coding the M/VM does not work efficiently, in more recent times a strucutre of UX designer w/ developer(s) makes more sense, the Dev having control of whole data pipeline while a UX designer feeding in the aesthetics, storyboards and user stories (A kind of artsy PM). I also think WPF is very different to web development as web is usually targeting millions of basic users while WPF usually geared towards advanced specialised UI requirements. I'm sure there are plenty but I have never seen/been involved with a WPF project that tried to strictly separate out the Xaml & M/VM devs the way it is done in web development as most web html frontend guys also program the behaviours in javascript, they are forced to by angular/react etc, with back end devs for a web client being the same as a .net wpf client, back end server devs.

Hope you manage to get the support you are looking for, I also would recommend FsXaml, it the best Xaml story for F# so far. I personally (just an opinion preference) would prefer to see a cleaner simpler UI model be designed and used in F# where the theme of simple syntax and composability continues through from Model to View.

ReedCopsey commented 5 years ago

I thought I'd chime in here, too -

FsXaml should be relatively straightforward to port and maintain on .NET Core 3. This should provide a reasonable mechanism for people who want to work with XAML files for WPF directly there, as it does on .NET Framework today.

That being said, FsXaml is not really as good as the C#/VB generation. While this works in many cases, there are significant disadvantages (most importantly, the lack of BAML generation). An official mechanism to use WPF in F# projects that included the BAML compilation would still add value, though FsXaml does provide a workaround for most cases that's reasonable and typically "good enough". I use it in production today, but typically only for "small screens" - large UI is still done in C# projects (with no code), merely to get BAML generation.

That being said, for any new project, I do agree that going with an MVU approach would add significant value, and I'd love to see the Fabulous approach ported to WPF at some point. Elmish.WPF and Gjallarhorn are the closest examples of this to date - both of which still use XAML as the view, but use an immutable model/update mechanism, but neither are really quite where they should be if you want a full MVU framework.

That being said, I think there are some significant technical challenges to overcome. I do disagree somewhat with @dsyme about this being "relatively cheap to make" - The WPF world is a bit different than Xamarin Forms - most WPF applications use a LOT of custom controls, and WPF's control model is quite a bit more complex than Xamarin Forms. Being able to handle styles and integrate 3rd party controls properly would be absolutely necessary if we wanted to really utilize WPF's strengths, and show a large value add over just using the WPF backend for Xamarin Forms with Fabulous today. Also, in WPF (unlike Xamarin Forms, from my understanding), there are some capabilities (mostly in styling) that are only available via XAML, and not really doable via code behind, which is likely to add some other complication to the design.

That being said, I'd be very happy to discuss this, or work with somebody on making this happen at some point - it's been on my list to try to tackle when I get some bandwidth. In the long run, I do agree that a Fabulous type of WPF framework is the best approach for F#, and would really have the potential to show significant value in the WPF ecosystem.

dsyme commented 5 years ago

"relatively cheap to make"

Yes, that was relative to the cost of building and maintaining VS/VSCode designer tooling :)

Hardt-Coded commented 5 years ago

That's my 2c worth. We should do it, and there are already community efforts in that direction, see Elmish.WPF.

Actually F# Fabulous works with Xamarin.WPF. I personally had used it for fast testing some implementations for my (mobile) "audio player app".

It compiles way faster than android and there is no slow emulator need. For a quick peak, it was nice.

fwaris commented 5 years ago

I also use FsXaml . I agree with @ReedCopsey in that we don't need code F# generation in WPF/XAML. FsXaml's XAML type provider (which does the code generation in a sense) is easy to use to wire up the UI. I have not had the need for XAML debugging either when using FsXaml.

BAML generation and support for editing XAML in F# projects would be great. While XAML editing works in F# projects, its needs to be better integrated.

I think the consensus is that WPF support for F# does not have to mirror C#'s and so can be done more cheaply.

I have not used Fabulous but have used React/Fable which is (finally) a civilized way of building web apps. I like that model as long as we have good visual feedback of the UI being constructed. In the web world this is possible through hot-loading of the code; would like to have the same for WPF.

charlesroddie commented 5 years ago

The title of this issue is misleading as it suggests that WPF does not support F#.

Based on the conversation the only thing that is relevant to this repo is a request for BAML generation in F# projects. FsXaml has its own repo (where a .Net Core port would be discussed), and any Elmish approach would be attempted in a separate repo (similarly to Fabulous).

ReedCopsey commented 5 years ago

@charlesroddie To be honest, there's a large scale of "support" for WPF in F# that would be possible, ranging from full templates with baml+code generation ala C# (not sure how that'd work), templates with designer support using FsXaml or similar, baml compilation with and (updated) fsxaml to take advantage of it, down to the status quo...

I wouldn't say that most of these options aren't relevant here, but I suspect in reality that BAML generation separate from the partial class work (so F# could hook into it) would probably be the most significant in terms of impact, as FsXaml is a reasonable alternative to the code generation aspects.

gerardtoconnor commented 5 years ago

For anyone who is not tied to Xaml, and wants to get a basic WPF app started quickly in F#, I created a new (basic) composable UI library for F# WPF. it uses computation expression UI instead of Xaml.

https://medium.com/@gerardtoconnor/skylight-composable-ui-hackery-with-wpf-3950634db451

https://github.com/gerardtoconnor/Skylight

jdh30 commented 5 years ago

I agree completely with @dsyme that a code-oriented solution is preferable to XAML when using F#. I have many WPF apps in production all written from scratch in F# with no XAML whatsoever.

On the .NET Framework the support for F#+WPF has always been great.

On .NET Core 3 I have managed to get WPF working from F# but only by manually hacking the fsproj file. So the only thing I'd really like to see is a "Hello world!" template for WPF on .NET Core 3 that gives you the appropriate fsproj file.

eriawan commented 4 years ago

@jdh30

So the only thing I'd really like to see is a "Hello world!" template for WPF on .NET Core 3 that gives you the appropriate fsproj file

I have a mini blog post on sample of using .NET Core 3.0 WPF/WinForms inside fsproj : https://fsharpmonologue.blogspot.com/2019/12/advent-2019-f-advent-2019-revisiting.html

Does this meet your need/requirement? I hope this helps.