2015-10-16 113 views
2

我想在Xamarin.Forms项目中使用Autofac。我成功创建了基本样本,甚至使用ViewFactory来处理更复杂的样本。在MasterDetailPage中使用Autofac和Xamarin.Forms导航

但是,我无法使用MasterDetailPage以及导航

我正在使用由Jonathan Yates编写的工厂和服务。你可以找到自己的代码here

我的应用程序引导程序:

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 + <> c.b__0_0()[0x00000]在C:\用户\ dushyantb \文件\的Visual Studio 2015 \项目\ TestIoc \ TestIoc \ TestIoc \ TestModule.cs:27 \ n at TestIoc.Views.PageProxy.get_Navigation()[0x00001] in C:\ Users \ dushyantb \ Documents \ Visual Studio 2015 \ Projects \ TestIoc \ TestIoc \ TestIoc \ Views \ PageProxy.cs:39 \ n在TestIoc.Navigator.get_Navigation()[0x00001]在C:\ Users \ dushyantb \ Documents \ Visual Studio 2015 \ Projects \ TestIoc \ TestIoc \ TestIoc \ Services \ Navigator.cs中:26 \ n在TestIoc.Navigator + d__8 `1 [TestIoc.ViewModels.TestViewModel2] .MoveNext()[0x0003a] in C:\ Users \ dushyantb \ Documents \ Visual Studio 2015 \ Projects \ TestIoc \ TestIoc \ TestIoc \ Services \ Navigator.cs:58“

我做错了什么?

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

+0

你能分享异常的堆栈跟踪吗? –

+0

我已经用堆栈跟踪更新了这个问题。请检查出来... –

回答

2

请务必不要覆盖PageResolver,例如。不采取乔纳森使用替代他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成功地。所以它应该工作。

在我的案例中,启动代码是

 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来切换MasterPages的详细信息:

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>()); 
    } 

} 

希望这可以帮助。

+0

谢谢! (()=> ((NavigationPage)Application.Current.MainPage).CurrentPage);我已经在使用'AutofacModule'中的MasterDetail场景的部分,但我也使用'builder.RegisterInstance >(()=> '在我自己的Module中,它是在'AutofacModule'之后注册的。因此,以前的注册从未执行,我不明白为什么! 只需要删除这一条语句。 –

+0

我不是专家,但我发现你的导航很奇怪。我可能是错的,但看起来你正在为'Detail'设置一个新页面,而不是导航。 –

+1

没错,这只是一个快速入侵。但是,您可以使用AutoFac将DetailView注册为.SingleInstance(),并且您将始终获得DetailPage的相同实例。 –

相关问题