使用Autofac和Xamarin.Forms

时间:2015-10-16 06:50:05

标签: c# xamarin.ios autofac xamarin.forms

我正在尝试在Xamarin.Forms项目中使用Autofac。我成功创建了基本样本,甚至将ViewFactory用于更复杂的样本。

但是,我无法将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 +&lt;&gt; c.b__0_0()[0x00000]在C:\ Users \ dushyantb \ Documents \ Visual Studio 2015 \ Projects \ TestIoc \ TestIoc \ TestIoc \ TestModule.cs:27 \ n在TestIoc.Navigator.get_Navigation的C:\ Users \ dushyantb \ Documents \ Visual Studio 2015 \ Projects \ TestIoc \ TestIoc \ TestIoc \ Views \ PageProxy.cs:39 \ n中的TestIoc.Views.PageProxy.get_Navigation()[0x00001] ()[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]在C:\ Users \ dushyantb \ Documents \ Visual Studio 2015 \ Projects \ TestIoc \ TestIoc \ TestIoc \ Services \ Navigator.cs:58“

我做错了什么?

注意:当没有MasterDetailPage时导航有效。

1 个答案:

答案 0 :(得分:3)

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

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

核心组件中PageResolver Func的默认实现负责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;
            }
        );

我已经使用Jonathan的框架成功地使用NavigationPage DetailViews测试了MasterDetail场景。所以它应该有用。

就我而言,引导代码是

        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&#39;详情:

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

}

希望这有帮助。