Reputation: 4292
I I have created a main page like this:
namespace Foo
open System
open Xamarin.Forms
open Xamarin.Forms.Xaml
type MainPage() =
inherit ContentPage()
let _ = base.LoadFromXaml(typeof<MainPage>)
let baseLayout = base.Content :?> AbsoluteLayout
let backgroundImage = baseLayout.Children.[0] :?> Image
let navigatonGrid = baseLayout.Children.[1] :?> Grid
let navigatonImage = navigatonGrid.Children.[0] :?> Image
let navigatonButton = navigatonGrid.Children.[1] :?> Button
let onButtonClicked sender args =
let loginPage = new NavigationPage(FacebookLoginPage())
Navigation.PushAsync(loginPage) |> ignore
let populateImages =
backgroundImage.Source <- ImageSource.FromResource("foo.jpg")
navigatonImage.Source <- ImageSource.FromResource("bar.jpg")
do
populateImages
navigatonButton.Clicked.AddHandler(new EventHandler(onButtonClicked))
And I wrap the Content page in the App.xaml.fs like this:
namespace foo
open Xamarin.Forms
type App() =
inherit Application(MainPage = NavigationPage(MainPage()))
However, it does not compile. I get this:
/Users/jamesdixon/Projects/foo/foo/MainPage.xaml.fs(9,9): Error FS0039: The value, namespace, type or module 'Navigation' is not defined. Maybe you want one of the following: NavigationPage
navigatonGrid navigatonButton navigatonImage
NavigationEventArgs (FS0039) (foo.Mobile.iOS)
However, I can't add the "this" keyword because I get this error:
/Users/jamesdixon/Projects/foo/foo.Mobile/MainPage.xaml.fs(9,9): Error FS0039: The value, namespace, type or module 'this' is not defined. Maybe you want one of the following: ThisAssembly (FS0039) (SameRoom.foo.iOS)
Is the problem that the button click cannot be static? If so, what is the correct syntax for the event handler?
Update: Based on the comments below, I tried this:
open System
open Xamarin.Forms
open Xamarin.Forms.Xaml
type MainPage(x) as self =
inherit ContentPage()
let _ = base.LoadFromXaml(typeof<MainPage>)
But now I get
The type 'ContentPage' is not defined
Upvotes: 1
Views: 277
Reputation: 660
I suspect that this is due to F# methods being translated to static methods (at least that's my understanding). The static method doesn't have access to the base type's method.
If you define onButtonClicked
as follows, it should work for you
member this.onButtonClicked sender args =
let loginPage = new NavigationPage(FacebookLoginPage())
this.Navigation.PushAsync(loginPage) |> ignore
Using the member this.onButtonClicked
syntax creates a class method, rather than a static method on the class. This then lets you access this.Navigation
on the class as you expect.
As for your problem with the constructor ordering, there are two solutions:
This link should explain how to do it in the constructor: https://fsharpforfunandprofit.com/posts/classes/#accessing-the-instance-via-this-in-a-do-block
However, according to that article, this is bad practice, an alternative would be to assign the handler in the OnStart
or PageAppearing
Lifecycle methods of the page.
Upvotes: 2