MvvmCross - 如何获取 iOS 视图以从不同的程序集加载?

MvvmCross - How to get iOS Views to load from a different assembly?

我试图让我的 xamarin-forms + mvvmcross 项目中的视图正确加载,但没有成功。

项目结构分解:

Project: Shared.Core - 100% cross platform code, view models, models, etc..

Project: Shared.Mobile - Xamarin-forms views

Project: iOS - uses shared views

Project: Android - uses shared views

Project: UWP - uses shared views

Project: WPF - uses WPF native views

我有一个使用 mvvmcross 的工作 WPF 项目,我正在尝试让移动设备从 iOS 开始运行。

iOS 项目仅在视图和视图模型位于同一程序集中时才加载视图。否则我得到:

Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch

通过获取 PCL Views 文件夹并将其移动到 iOS 项目,可以从这个示例项目中看出同样的情况。

https://github.com/MvvmCross/MvvmCross-Forms/tree/master/Samples/Example001XAML

我也试过以下方法都无济于事:

Setup.cs

protected override IEnumerable<Assembly> GetViewModelAssemblies()
{
    var result = base.GetViewModelAssemblies();
    var assemblyList = result.ToList();
    assemblyList.Add(typeof(FirstViewModel).Assembly);
    return assemblyList.ToArray();
}

protected override IEnumerable<Assembly> GetViewAssemblies()
{
    var result = base.GetViewAssemblies();
    var assemblyList = result.ToList();
    assemblyList.Add(typeof(FirstPage).Assembly);
    return assemblyList.ToArray();
}
    
protected override void InitializeViewLookup()
{
    base.InitializeViewLookup();

    var vmLookup = new Dictionary<Type, Type> {
        {typeof (FirstViewModel), typeof (FirstPage)},
        {typeof (AboutViewModel), typeof (AboutPage)}
    };

    var container = Mvx.Resolve<IMvxViewsContainer>();
    container.AddAll(vmLookup);
}

我刚刚在 Forms Presenter 核心中修复了这个问题,现在可以使用了!您在覆盖 GetViewsAssembliesInitializeViewLookup 方面走在了正确的轨道上。如果一开始就正确实施了 Presenter,那么它应该是这样工作的。

无论如何,有了这个 Pull Request 的新变化,它的工作方式是:

要么覆盖 GetViewsAssembliesInitializeViewLookup 在内部将视图映射到视图模型,从找到的视图中告诉 MvvmCross 寻找它们。 Setup.cs 中的代码类似于:

protected override IEnumerable<Assembly> GetViewAssemblies()
{
    var result = base.GetViewAssemblies();
    var assemblyList = result.ToList();
    assemblyList.Add(typeof(FirstPage).Assembly);
    return assemblyList;
}

其中 FirstPage 是包含视图的程序集中的页面之一。

或者您可以在 InitializeViewLookup 中明确告诉 MvvmCross 如何将 View 映射到 ViewModels:

protected override void InitializeViewLookup()
{
    base.InitializeViewLookup();

    var vmLookup = new Dictionary<Type, Type> {
        {typeof (FirstViewModel), typeof (FirstPage)}
    };

    var container = Mvx.Resolve<IMvxViewsContainer>();
    container.AddAll(vmLookup);
}