Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantage of FsXaml type provider over XamlReader

Tags:

xaml

f#

fsxaml

F# doesn't support partial classes nor precompilation of XAML files. The workaround: instead of compile-time code behind, load graphical object definitions at runtime. There are various ways to supply XamlReader with the content of a referenced resource file.

open System.Windows

// from Resource
let uri = System.Uri "pack://application:,,,/AssemblyName;component/MainWindow.xaml"
let info = Application.GetResourceStream uri
let wnd = Markup.XamlReader.Load info.Stream :?> Window

// from Embedded resource
let assembly = System.Reflection.Assembly.GetExecutingAssembly()
let stream = assembly.GetManifestResourceStream "MainWindow.xaml"
let wnd  = Markup.XamlReader.Load stream :?> Window

Type providers should be able to shift at least part of that effort back to compile-time.

open FsXaml
type MainWindow = XAML<"MainWindow.xaml"> 
let mainwnd = new MainWindow()
let wnd = mainwnd.Root

The gain in type safety (and discovery) seems to be marginal: one runtime type cast less per resource. Are there other advantages?

like image 463
kaefer Avatar asked Jun 16 '15 05:06

kaefer


2 Answers

The gain in type safety (and discovery) seems to be marginal: one runtime type cast less per resource.

There are other advantages here, even in the code you displayed. Using FsXaml is far more concise in your example, and fully type safe. It will also fail at compile time if there are major issues in your XAML files, where using XAML Loader defers this to runtime.

Are there other advantages?

There are many advantages -

  • Shorter code
  • Type safety
  • Named elements exposed as properties in a type safe manner
  • (Most important) Creates actual types corresponding to your XAML types

The last point is really the "killer" advantage of FsXaml vs XamlReader - without this, it's nearly impossible to do anything beyond "toy" projects in WPF. You need to have "real types" corresponding to your types if you want to be able to embed XAML.

For example, if you want to use UserControls you develop as data templates, you need that UserControl to be an actual type, not just some XAML as a resource. Using XamlReader, there's no way to reference that from other XAML. You also can't reuse resources, pull data into your Application, or many other things (without resorting to hand-writing a huge amount of plumbing to do it at runtime).

In addition, with FsXaml 2+, you can subclass types and provide full logic within the "code behind", similarly (though differently) from how you work in C#.

This brings Xaml much, much closer to the experience when working in C# - There is still no BAML compilation (the one disadvantage), but otherwise, you get an experience that is effectively on-par with C# when working from F# with WPF.

like image 146
Reed Copsey Avatar answered Nov 03 '22 12:11

Reed Copsey


A type provider checks things at compile time, the Xaml reader works at run time.
Thus errors are either detected at compile or at run time. It is pretty obvious that finding errors earlier in the development process is better.

like image 33
weismat Avatar answered Nov 03 '22 14:11

weismat