dotnet / MobileBlazorBindings

Experimental Mobile Blazor Bindings - Build native and hybrid mobile apps with Blazor
MIT License
1.2k stars 171 forks source link

get XF's element from Blazor's one #106

Open ysmoradi opened 4 years ago

ysmoradi commented 4 years ago

How can I get XF's element from Blazor's one? I've one Blazor ContentPage (Microsoft.MobileBlazorBindings.Elements.ContentPage) and I'd like to get its equivalent Xamarin.Forms.ContentPage

ysmoradi commented 4 years ago

Ping!

doug-m-alexander commented 4 years ago

This is based off of the HelloWorld Sample. You can do what you are asking by changing the App.cs lines 22 and 23 to.

Xamarin.Forms.Label a = new Xamarin.Forms.Label{
    Text = "Hello, Forms!",
    VerticalOptions = LayoutOptions.CenterAndExpand,
    HorizontalOptions = LayoutOptions.CenterAndExpand,
};
MainPage =  new Xamarin.Forms.ContentPage()
{
Content = a
};
host.AddComponent<Counter>(parent: MainPage);

I then commented out the content of the Counter.razor file.

What are you trying to achieve here, usage of an element that is not wrapped yet?

ysmoradi commented 4 years ago

I'd like to write a custom shell page factory. It requires me to return an object of type XF.Page

doug-m-alexander commented 4 years ago

I'll refer you to the docs, since I have no experience with that.

Eilon commented 4 years ago

Hi, every Blazor control has a NativeControl property that you can use to get the Xamarin.Forms control. The docs aren't updated yet but you can see a description and example in the PR: https://github.com/xamarin/MobileBlazorBindings/pull/45

ysmoradi commented 4 years ago

Hi, every Blazor control has a NativeControl property that you can use to get the Xamarin.Forms control. The docs aren't updated yet but you can see a description and example in the PR: #45

Yeah, but it's not filled as soon as you instantiate the page! It seems it gets filled during the page lifecycle. At the moment I've no idea how to add a page to shell route registry. Note that it's possible to create a control in xamarin forms and using that in xamarin classic as every xf control has a method that returns its equivalent native control. For example, we can get a Fragment in android from xamarin forms content view! Now, if we write the same ContentView in blazor, we can't simply say

new MyContentView().NativeControl.CreateViewController()

or

new MyContentView().NativeControl.CreateSupportFragment()

Consider followings shell scenario too:

    public class BlazorPageRouteFactory<TPage> : RouteFactory
        where TPage : Microsoft.MobileBlazorBindings.Elements.ContentPage
    {
        public override Element GetOrCreate()
        {
            var serviceProvider = ((App)Application.Current).EmblazonHost.Services;

            var page = serviceProvider.GetRequiredService<TPage>();

            return page.NativeControl; // NullReferenceException while getting NativeControl!
        }
    }

Which is intended to be called as:

Routing.RegisterRoute("third-view", new BlazorPageRouteFactory<ThirdView>());
<PackageReference Include="Microsoft.MobileBlazorBindings" Version="0.2.42-preview" />
Eilon commented 4 years ago

From where in the Blazor code are you trying to access the NativeControl property? If it it too early in the lifecycle you are correct that it won't yet be available (it can't tell you the control if the control doesn't exist yet). But there might be another lifecycle point that would work for this scenario.

ysmoradi commented 4 years ago

From where in the Blazor code are you trying to access the NativeControl property? If it it too early in the lifecycle you are correct that it won't yet be available (it can't tell you the control if the control doesn't exist yet). But there might be another lifecycle point that would work for this scenario.

So, how we can use shell pages using RouteFactory? Note that there is no such feature in Blazor/Shell sample!

Eilon commented 4 years ago

Support for the Shell component is very limited right now in Mobile Blazor Bindings. And, there is also some bug in it that I have tried investigating but don't have a solution for, which causes an exception to get thrown in even some common scenarios.

ysmoradi commented 4 years ago

I see. Note that If we can access NativeControl from the very beginning of the component lifecycle (I mean after construction) it opens new set of opportunities.

In the end, may I have access to the issue of Blazor/XF/Shell? Thanks in advance.

Eilon commented 4 years ago

Support for Shell is tracked here: https://github.com/xamarin/MobileBlazorBindings/issues/11

Here's something that might be worth trying in the meantime: Can you handle the containing Page's OnAppearing event and try to access the Shell component from there?

Eilon commented 4 years ago

And I just published some docs on accessing native controls here: https://docs.microsoft.com/mobile-blazor-bindings/advanced/access-native-controls