Forum Xamarin.Forms

Partial Views Autowire Injection Didn't work Prism

Xam_amrXam_amr Member ✭✭✭
edited March 2020 in Xamarin.Forms

I am using Prism Through my app and I Created Custom View Toolbar and want to implement Navigation service anywhere I Called this Toolbar . I only find one example bud didn't work with me.

Content View

    <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
                 xmlns:prism="clr-namespace:Prism.Ioc;assembly=Prism.Forms"
                 xmlns:mvvm="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
                 x:Name="AppToolbarview" 
                 xmlns:local="clr-namespace:IFind.Views"
                 BackgroundColor="#20019C"
                 x:Class="IFind.Views.AppToolbar">
        <local:AppToolbar mvvm:ViewModelLocator.AutowirePartialView="{x:Reference AppToolbarview}" />
        <ContentView.Content>
                <ImageButton x:Name="backbtn" Grid.Row="0" HorizontalOptions="Start" HeightRequest="30" WidthRequest="25" VerticalOptions="CenterAndExpand" BackgroundColor="Transparent" Grid.Column="0" Source="back.png" Command="{Binding BackCommand}"  Aspect="AspectFit"></ImageButton>
        </ContentView.Content>
    </ContentView>

View Model

        public class AppToolbarViewModel : BindableBase
        {
            private INavigationService _navigationService;

            public DelegateCommand BackCommand => new DelegateCommand(Back);

            private void Back()
            {
                _navigationService.GoBackAsync();
            }

            public AppToolbarViewModel(INavigationService navigationService)
            {
                _navigationService = navigationService;
            }
        }

I tried this and Then tried to Register the service manually in app.cs

ViewModelLocationProvider.Register<AppToolbar,AppToolbarViewModel>();
but app crashing in page which contains Apptoolbar

Native Crash Reporting

Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries

used by your application.

No native Android stacktrace (see debuggerd output).

=================================================================

Basic Fault Address Reporting

Memory around native instruction pointer (0xcd19c3ca):0xcd19c3ba c0 5e 5f
Any help? many thanks

Best Answer

Answers

  • Xam_amrXam_amr Member ✭✭✭

    Thanks @NMackay It's works

  • SagarPanwalaSagarPanwala USMember ✭✭✭
    edited August 2020

    @NMackay : If you can help me it would be good. I've raised my question on SO.
    but I'm expecting more generic solution instead of using MessagingCenter.

    Issue I'm facing is, in CustomView's ViewModel I'm getting NavigationService, but looks like it's not of Parent Page, it's from custom view and in Xamarin Forms Navigation should be done from Page.
    So what I need is can we pass navigation service by tweaking the following code.

        protected override void ConfigureViewModelLocator()
        {
            ViewModelLocationProvider.SetDefaultViewModelFactory((view, type) =>
            {
                Page page = null;
                switch (view)
                {
                    case Page page1:
                        page = page1;
                        break;
                    case Element customView:
                        page = GetPageFromElement(customView);
                        // Existing parameter with the Page
                        break;
                }
    
                var navService = CreateNavigationService(page);
                return Container.Resolve(type, type.GetType().Name, navService);
            });
         }
    

    I don't find the solution to pass navigation service in , or I can I don't know proper syntax.
    Container.Resolve(type, type.GetType().Name, navService);

  • NMackayNMackay GBInsider, University admin
    edited August 2020

    @SagarPanwala

    You can navigate from partial nav's like you normally would a page VM, you don't have to pass the navigation service, it gets resolved automatically by Prism.

    I wrote this a while back to allow basic region navigation in page,

    https://github.com/mackayn/Regions, to resolve a partial view you have to pass in the parent page I believe
    https://github.com/mackayn/Regions/blob/master/PrismRegions.Framework/Mvvm/Regions/RegionService.cs#L115

    Prism8 has region support coming so hopefully these scenarios will be a little less fiddly.

    Just remember, as you creating these partial views & viewmodels on the fly, your are responsible for unregistering them.
    https://github.com/mackayn/Regions/blob/master/PrismRegions.Framework/Mvvm/Regions/RegionManager.cs#L17

  • stesvisstesvis USMember ✭✭✭✭
    edited January 2

    @NMackay do you know if there is a way to bind the partial view to a property in the parent page view model?

    HomePage.xaml:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:prism="http://prismlibrary.com"
                 prism:ViewModelLocator.AutowireViewModel="True"
                 x:Class="Tradeality.Mobile.Views.HomePage"
                 x:Name="homePage"
                 xmlns:views="clr-namespace:Tradeality.Mobile.Views">
    
        <ContentPage.Content>
            <views:HomePartialPage prism:ViewModelLocator.AutowireViewModel="True" />
        </ContentPage.Content>
    
    </ContentPage>
    

    HomePageViewModel:

            public HomePartialPageViewModel MyHomePartialPage { get; set; }
    
            public override void OnNavigatedTo(INavigationParameters parameters)
            {
                base.OnNavigatedTo(parameters);
    
                MyHomePartialPage.MyMethod();
            }
    

    Is it possible to do something like that?

  • NMackayNMackay GBInsider, University admin
    edited January 2

    The only way you could probably do it in XAML is with ancestor level binding to bind to a property in the parent VM.
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/relative-bindings#bind-to-an-ancestor. In this scenario it's messy though and your creating a reference between both VM's which you'd have to be careful with when it comes to parent page tear down, you'd certainly have to use destroy to null that vm reference to avoid a memory leak.

    Without fully knowing the scenario, for this code type scenario I'd probably use EventAggregator so HomePageViewModel can message HomePartialPageViewModel with no strong reference between the pair, EA is there for these scenarios.
    https://prismlibrary.com/docs/event-aggregator.html

    Another approach in Prism is CompositeCommand
    https://prismlibrary.com/docs/composite-commands.html

    This place is closing down soon so I'd probably ask on Prism's github site or the slack channel for advice. I'd use EventAggregator in this scenario most likely or a Singleton service with an eventhandler.

    Just remember, the partial views also get the lifecycle events such as OnNavigatedTo if implemented in the Partial viewmodels.

  • NMackayNMackay GBInsider, University admin
    edited January 2

    Also worth sponsoring either Brian or Dan (or both), it means support from the maintainers is available to you.

    https://github.com/sponsors/dansiegel#sponsors
    https://github.com/sponsors/brianlagunas#sponsors

Sign In or Register to comment.