【问题标题】:MvvmCross - How to get iOS Views to load from a different assembly?MvvmCross - 如何让 iOS 视图从不同的程序集加载?
【发布时间】:2016-05-21 07:09:03
【问题描述】:

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

项目结构分解:

项目:Shared.Core - 100% 跨平台代码,查看模型、模型、 等等。

项目:Shared.Mobile - Xamarin 表单视图

项目:iOS - 使用共享视图

项目:Android - 使用共享视图

项目:UWP - 使用共享视图

项目:WPF - 使用 WPF 原生视图

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

只有当视图和视图模型在同一个程序集中时,iOS 项目才会加载视图。否则我会得到:

Foundation.MonoTouchException:抛出 Objective-C 异常。姓名: NSInternalInconsistencyException 原因:应用程序窗口是 期望在应用程序结束时有一个根视图控制器 发射

通过获取 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);
}

【问题讨论】:

  • 哦等等。我重读了你的帖子,现在我在想。您的 AppDelegate 中发生了什么?它抱怨在应用程序启动结束时没有出现任何窗口,这意味着那里可能缺少某些东西。 AppDelegate.cs 请。
  • 从 Example001XAML 项目中,从字面上看,唯一的更改是将包含 xaml 页面的“Pages”文件夹向下移动到 iOS 项目中,从而将视图与视图模型分开(就像我的实际项目一样做)。没有对 AppDelegate 进行任何更改。然后将 Setup.cs 更改为发布的内容以尝试修复它。
  • 在深入了解内部结构后,我发现这里有一个问题:github.com/MvvmCross/MvvmCross-Forms/blob/master/… 问题是它总是在与 ViewModel 相同的 Assembly 中查找并忽略 ViewLookup。将尽快解决此问题并为您提供解决方法。
  • 这已在 viewlookup 分支中修复:github.com/MvvmCross/MvvmCross-Forms/pull/46 您可以等我推出新的 NuGet 包(可能在明天的某个时间),或者您可以检查分支并自己构建它。我将在下面编辑我的答案。

标签: cross-platform mvvmcross xamarin-forms


【解决方案1】:

我刚刚在 Forms Presenter 核心中修复了这个问题,所以它现在可以工作了!你在正确的轨道上覆盖GetViewsAssembliesInitializeViewLookup。如果演示者一开始就被正确实现,那么它应该是这样工作的。

无论如何,随着 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 如何将 Views 映射到 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);
}

【讨论】:

  • 非常感谢您查看此内容,但我尝试了您的建议(如我上面的编辑所示),但仍然遇到相同的错误。任何进一步的建议将不胜感激。
  • 你还有什么想法吗?
  • 制作一个repro样本放在github上,我会试一试
  • 这些修复程序现已推送到 NuGet。 nuget.org/packages/MvvmCross.Forms.Presenter/4.0.2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多