locked
Partial Views Autowire Injection Didn't work Prism RRS feed

  • Question

  • User367403 posted

    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

    Thursday, March 5, 2020 10:41 AM

Answers

  • User76049 posted

    it definitely works fine, with DI, we use it everywhere in our app

    <NavigationPage.TitleView> <components:NavBar mvvm:ViewModelLocator.AutowirePartialView="{x:Reference RootPage}" /> </NavigationPage.TitleView>

    If your component doesn't live in the default views folder you will have to override the viewmodellocator

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, March 5, 2020 12:03 PM

All replies

  • User76049 posted

    it definitely works fine, with DI, we use it everywhere in our app

    <NavigationPage.TitleView> <components:NavBar mvvm:ViewModelLocator.AutowirePartialView="{x:Reference RootPage}" /> </NavigationPage.TitleView>

    If your component doesn't live in the default views folder you will have to override the viewmodellocator

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, March 5, 2020 12:03 PM
  • User367403 posted

    Thanks @NMackay It's works

    Thursday, March 5, 2020 12:46 PM
  • User75709 posted

    @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);

    Sunday, August 2, 2020 5:13 AM
  • User76049 posted

    @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

    Sunday, August 2, 2020 7:08 PM
  • User28603 posted

    @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: ```xml

    <ContentPage.Content>
        <views:HomePartialPage prism:ViewModelLocator.AutowireViewModel="True" />
    </ContentPage.Content>
    

    ```

    HomePageViewModel: ```cs public HomePartialPageViewModel MyHomePartialPage { get; set; }

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

    ```

    Is it possible to do something like that?

    Saturday, January 2, 2021 12:28 AM
  • User76049 posted

    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.

    Saturday, January 2, 2021 10:48 AM
  • User76049 posted

    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

    Saturday, January 2, 2021 12:03 PM