elmish / Elmish.WPF

Static WPF views for elmish programs
Other
431 stars 71 forks source link

XAML type provider #142

Open TysonMN opened 5 years ago

TysonMN commented 5 years ago

This issue spun out of https://github.com/elmish/Elmish.WPF/issues/141#issuecomment-538105026.

The general question is

Is it possible to improve type safety by using XAML type provider?

TysonMN commented 5 years ago

Replying to https://github.com/elmish/Elmish.WPF/issues/141#issuecomment-538117978.

If you introduce a type provider in Elmish.WPF, then perhaps consider make it optional in some way if it isn't too much of a bother. E.g. make it possible to bind with either magic string or through the type provider, so that if the type provider fails, at least the magic string mechanism saves the day.

Yes, that is my thinking as well. The magic string approach isn't that bad, especially when you consider that essentially all GUI frameworks do something similar. I don't have any current plans to look into this, but I hope to do so eventually. Thanks for the links and short descriptions :)

BentTranberg commented 5 years ago

I agree. Magic strings definitely isn't the biggest problem we deal with. Nevertheless GUI breaks from time to time because a string depended on some identifier that was refactored (renamed). Using dedicated local types for bindings and streamings, or running unit tests that checks with 'nameof', are examples of how to avoid or detect such breaking changes. I like doing heavy refactorings to keep my code tidy, so I also depend heavily on that kind of security around my code. It works.

cmeeren commented 5 years ago

If you use design-time VMs (check the readme), the tooling might warn you if there's a binding from XAML that don't exist in the VM.

Not sure if design-time VMs work with netcoreapp3.0 by the way, because it seems that the XAML designer currently doesn't support Project Code.

TysonMN commented 5 years ago

Nevertheless GUI breaks from time to time because a string depended on some identifier that was refactored (renamed). ... I like doing heavy refactorings to keep my code tidy, so I also depend heavily on that kind of security around my code. It works.

Me too. My goal is to have all the magic strings be string literals passed into Elmish.WPF bindings. That way, I can't break anything with using Visual Studio's Refactor-Rename. After I make the changed described in https://github.com/elmish/Elmish.WPF/issues/131#issuecomment-538398038, I will once again be achieving this goal with my work project.

TysonMN commented 5 years ago

...it seems that the XAML designer currently doesn't support Project Code.

What is "Project Code"?

cmeeren commented 5 years ago

I'm no expert, but the designer basically runs your project so that you get the design-time data you want.

In the .NET framework designer there's a button to toggle it on/off. I can't find that button when using .NET Core.

BentTranberg commented 5 years ago

If you use design-time VMs

I do, but I don't reuse the runtime model for that. I find it much easier to simply create a class or two or three with properties and whatnots. My goal, obviously, is just to deliver some fake data for design time. I couldn't care less whether the runtime and design-time VM's are properly aligned in all manners. After all, there is no interactivity either, so why bother with a more complex model that includes the time aspect when the data is all static. The visual design generally becomes easier this way, at least for me.

update Nov 2020 : Problems solved, I now use Elmish.WPF proper design time models.

cmeeren commented 5 years ago

Some benefits of a using runtime model are 1) you're guaranteed to keep the design-VM props in sync with the bindings (since they're the same), giving you useful Intellisense and warnings when changing/renaming the bindings in bindings, and 2) you already have bindings, so you don't need to create another class.

Making a simple, separate design-time VM is a perfectly reasonable tradeoff, though.

TysonMN commented 5 years ago

This issue is related to #13

TysonMN commented 4 years ago

In case its helpful, Pluralsight has a course about how to create a type provider. Building F# Type Providers by Dave Fancher

light-pigeon commented 4 years ago

@cmeeren said:

...giving you useful Intellisense and warnings when changing/renaming the bindings in bindings

But I cannot see a warning in the designer when the binding does not match the binding name on the VM. (see animation on sample project)

Animation

TysonMN commented 3 years ago

I useful link it this issue is to the FsXaml project (which was lasted updated in 2018).

marner2 commented 2 years ago

For the record, I have a solution to this documented in #494. It involves replacing the type lists into an F# ViewModel type, implemented through a helper. This solution therefore leverages the types directly. It should work completely inline with the current solution.

TysonMN commented 2 years ago

Very interesting. I am excited to try this.

marner2 commented 2 years ago

What about directly subclassing Binding in WPF to take a Property accessor and a message type for setting directly in XAML? This would skip any kind of bindings directly, and you could "bind" to the model type directly in the view.

Command bindings could work the same way, with a subclass of CommandBinding and just supplying the name of the message.

EDIT: nevermind I see that most of the classes here are sealed and use other helpers to actually do the work.