Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting the backing classes for UI elements #342

Merged
merged 4 commits into from
Feb 23, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/views-extending.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,21 @@ need not be added, you can set them on elements using the helper `With`, usable
View.Map(hasZoomEnabled = true, hasScrollEnabled = true).With(horizontalOptions = LayoutOptions.FillAndExpand)
```

### Example: MasterDetailPage without a toolbar on UWP with custom ViewBuilders

Fabulous uses ViewBuilders to create the underlying Xamarin.Forms classes. Customizing ViewBuilders is not the recommended way for custom controls but it is a great solution for overridden controls like in the following example:

```fsharp
type MasterDetailPageWithoutToolbar() =
inherit Xamarin.Forms.MasterDetailPage()
override __.ShouldShowToolbarButton() = false

Fabulous.DynamicViews.ViewBuilders.CreateFuncMasterDetailPage <- fun () ->
upcast(new MasterDetailPageWithoutToolbar())

View.MasterDetailPage() // this now uses MasterDetailPageWithoutToolbar
```

See also:

* [Core Elements](views-elements.md)
Expand Down
10 changes: 5 additions & 5 deletions tests/Generator.Tests/CodeGeneratorTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ type ViewProto() =
TypeToInstantiate = "Fabulous.DynamicViews.CustomListView"
Parameters = [||] }
"""
static member val CreateFuncListView : (unit -> Xamarin.Forms.ListView) = (fun () -> ViewBuilders.CreateListView())
static member val CreateFuncListView : (unit -> Xamarin.Forms.ListView) = (fun () -> ViewBuilders.CreateListView()) with get, set

static member CreateListView () : Xamarin.Forms.ListView =
failwith "can't create Xamarin.Forms.ListView"
Expand All @@ -187,7 +187,7 @@ type ViewProto() =
TypeToInstantiate = "Fabulous.DynamicViews.CustomListView"
Parameters = [||] }
"""
static member val CreateFuncListView : (unit -> Xamarin.Forms.ListView) = (fun () -> ViewBuilders.CreateListView())
static member val CreateFuncListView : (unit -> Xamarin.Forms.ListView) = (fun () -> ViewBuilders.CreateListView()) with get, set

static member CreateListView () : Xamarin.Forms.ListView =
upcast (new Fabulous.DynamicViews.CustomListView())
Expand All @@ -204,7 +204,7 @@ type ViewProto() =
TypeToInstantiate = "Fabulous.DynamicViews.CustomListView"
Parameters = [| "parameter1"; "parameter2" |] }
"""
static member val CreateFuncListView : (unit -> Xamarin.Forms.ListView) = (fun () -> ViewBuilders.CreateListView())
static member val CreateFuncListView : (unit -> Xamarin.Forms.ListView) = (fun () -> ViewBuilders.CreateListView()) with get, set

static member CreateListView () : Xamarin.Forms.ListView =
match parameter1, parameter2 with
Expand Down Expand Up @@ -481,7 +481,7 @@ type ViewBuilders() =
match text with None -> () | Some v -> attribBuilder.Add(ViewAttributes.TextAttribKey, (v))
attribBuilder

static member val CreateFuncButton : (unit -> Xamarin.Forms.Button) = (fun () -> ViewBuilders.CreateButton())
static member val CreateFuncButton : (unit -> Xamarin.Forms.Button) = (fun () -> ViewBuilders.CreateButton()) with get, set

static member CreateButton () : Xamarin.Forms.Button =
upcast (new Xamarin.Forms.Button())
Expand Down Expand Up @@ -626,4 +626,4 @@ module ViewElementExtensions =
let minimumMaximum (value: float * float) (x: ViewElement) = x.MinimumMaximum(value)
/// Adjusts the SliderValueChanged property in the visual element
let sliderValueChanged (value: Xamarin.Forms.ValueChangedEventArgs -> unit) (x: ViewElement) = x.SliderValueChanged(value)
"""
"""
2 changes: 1 addition & 1 deletion tools/Generator/CodeGenerator.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ module CodeGenerator =
w

let generateCreateFunction (data: CreateData) (w: StringWriter) =
w.printfn " static member val CreateFunc%s : (unit -> %s) = (fun () -> ViewBuilders.Create%s())" data.Name data.FullName data.Name
w.printfn " static member val CreateFunc%s : (unit -> %s) = (fun () -> ViewBuilders.Create%s()) with get, set" data.Name data.FullName data.Name
w.printfn ""
w.printfn " static member Create%s () : %s =" data.Name data.FullName
Copy link
Member

@TimLariviere TimLariviere Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, you might want to extend this Create%s method instead.
It's the one with the upcast.

Nevermind, just realized it's a concrete method and can't be overwritten. :)

Copy link
Author

@sdaves sdaves Feb 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I went with the public setter. I first tried adding a static extension method of the same name in the same namespace, but in my project and not in Fabulous, hoping that would override the default static methods in ViewBuilders(), but that didn't work so I went with the property setters.


Expand Down