使用导航MasterDetailPage与Autofac和Xamarin.Forms

本文关键字:Xamarin Forms Autofac 导航 MasterDetailPage | 更新日期: 2023-09-27 18:18:01

我正在尝试在Xamarin中使用Autofac。形式的项目。我成功地创建了基本的样本,甚至使用ViewFactory创建了一些更复杂的样本。

然而,我无法使用MasterDetailPage 以及导航

我使用的是Jonathan Yates写的工厂和服务。你可以找到他的代码here

My Application Bootstrapper:

protected override void ConfigureApplication(IContainer container)
{
    var viewFactory = container.Resolve<IViewFactory>();
    var mainPage = viewFactory.Resolve<TestViewModel1>();
    var navigationPage = new NavigationPage(mainPage);
    var masterPage = new ContentPage();
    masterPage.Title = "asd";
    _application.MainPage = new MasterDetailPage()
    {
        Master = masterPage,
        Detail = navigationPage
    };
}

我的TestViewModel1有一个导航到TestViewModel2的命令:

ButtonCommand = new Command(async()=>await _navigator.PushAsync<TestViewModel2>());

然而,应用程序崩溃了,异常说

不能从源类型强制转换为目标类型。

Navigator推送下一页时发生。

异常堆栈

:

", TestIoc.TestModule + & lt的在c。b__0_0 () [0x00000] in C:'Users'dushyantb'Documents'Visual Studio 2015'Projects' testoc ' testoc ' testoc 'TestModule.cs:27 'n at testoc . view . pageproxy . htmlget_Navigation () [0x00001] in C:'Users'dushyantb'Documents'Visual Studio 2015'Projects' testoc ' testoc ' testoc 'Views'PageProxy.cs:39 'n at testoc . navigator。get_Navigation () [0x00001] in C:'Users'dushyantb'Documents'Visual Studio 2015'Projects' testoc ' testoc 'Services'Navigator.cs:26 'n at testoc . navigator +d__8 ' 1[testoc . viewmodels . testviewmodel2].MoveNext () [0x0003a] in C:'Users'dushyantb'Documents'Visual Studio 2015'Projects' testoc ' testoc 'Services'Navigator.cs:58 "

我做错了什么?

注意:导航工作时,没有MasterDetailPage

使用导航MasterDetailPage与Autofac和Xamarin.Forms

请确保不要覆盖PageResolver,例如:不要使用Jonathan在WeatherApp示例中使用的重写:

builder.RegisterInstance<Func<Page>>(() => ((NavigationPage)Application.Current.MainPage).CurrentPage);

核心组件中PageResolver函数的默认实现负责MasterDetail场景。看到AutoFacModule.cs:

            // default page resolver
            builder.RegisterInstance<Func<Page>>(() =>
            {
                // Check if we are using MasterDetailPage
                var masterDetailPage = Application.Current.MainPage as MasterDetailPage;
                var page = masterDetailPage != null 
                    ? masterDetailPage.Detail 
                    : Application.Current.MainPage;
                // Check if page is a NavigationPage
                var navigationPage = page as IPageContainer<Page>;
                return navigationPage != null 
                    ? navigationPage.CurrentPage
                        : page;
            }
        );

我已经测试了MasterDetail场景与NavigationPage DetailViews与Jonathan的框架成功。所以它应该工作。

在我的例子中,引导代码是
        protected override void ConfigureApplication(IContainer container)
        {
            // set main page
            var viewFactory = container.Resolve<IViewFactory>();
            var mainPage = viewFactory.Resolve<MainPageViewModel> ();
            _application.MainPage = mainPage;
        }

这意味着,我有一个MainPageView,这是一个MasterDetailPage,它负责设置它的子视图:

    public class MainPage : MasterDetailPage
    {
        public MainPage (IViewFactory viewfactory)
        {
            Master = viewfactory.Resolve<MenuPageViewModel>();
            Detail = new NavigationPage (viewfactory.Resolve<DetailViewModel1>());
        }
    }

MenuPageViewModel也使用IViewFactory来切换母版页的Detail:

public class MenuPageViewModel : ViewModelBase
{
    IViewFactory _viewFactory;
    public MenuPageViewModel (IViewFactory viewFactory)
    {
        _viewFactory = viewFactory;
        ShowDetail1Command = new Command (ShowDetail1);
        ShowDetail2Command = new Command (ShowDetail2);
    }

    public ICommand ShowDetail1Command { get; set;}
    public void ShowDetail1() {
        var mainPage = _viewFactory.Resolve<MainPageViewModel> ();
        ((MasterDetailPage)mainPage).Detail = new NavigationPage (_viewFactory.Resolve<DetailViewModel1> ());
    }
    public ICommand ShowDetail2Command { get; set;}
    public void ShowDetail2() {
        var mainPage = _viewFactory.Resolve<MainPageViewModel> ();
        ((MasterDetailPage)mainPage).Detail = new NavigationPage (_viewFactory.Resolve<DetailViewModel2> ());
    }
}