【问题标题】:PRISM navigationService is null in ViewModel constructorPRISM navigationService 在 ViewModel 构造函数中为空
【发布时间】:2019-12-28 13:11:03
【问题描述】:

情况:我有这些物品:

MainMenuView
MainMenuViewModel
MainMenuPage

MainMenuPage 包含 MainMenuView,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:xxx_App.Pages"
             xmlns:views="clr-namespace:xxx_App.Views"
             x:Class="xxx_App.Pages.MainMenuPage">
    <ContentPage.Content>
        <StackLayout>           
            <views:MainMenuView />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

MainMenuView 自动连接到 MainMenuViewModel,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="xxx_App.Views.MainMenuView">
  <ContentView.Content>
        <StackLayout>
            // SOME BUTTONS
        </StackLayout>
  </ContentView.Content>
</ContentView>

这是我的 MainMenuViewModel 构造函数:

public MainMenuViewModel(INavigationService navigationService)
{
    // A breakpoint here does break the software, but navigationService is null
}

问题:问题在于 MainMenuViewModel 的构造函数中的 navigationService 为 null。构造函数确实被调用,所以我认为这不是自动布线的问题。构造函数被 PRISM 框架的自动装配函数调用。

有人知道为什么 navigationService 为空吗?

提前致谢!

编辑:

解决方案:我部分使用了 Roubachof 的解决方案。

我创建了一个 MainMenuPageViewModel。我摆脱了 MainMenuViewModel,因为不再需要了。我将 ICommands(在 cmets 中提到)移动到新的 MainMenuPageViewModel。

很明显,在阅读 PRISM 时,我对页面和视图感到困惑。我以为视图有视图模型,但实际上页面有视图模型。这是因为 MVVM 和 Xamarin.Forms 使用不同的术语。既然我知道了这一点,我将去对我的应用程序的结构进行一些更改。

【问题讨论】:

  • 您可以在创建“MainMenuViewModel”的位置添加代码吗?我猜这是通过 MainMenuPageViewModel 中的视图模型定位器,但让我们看看。
  • MainMenuViewModel 由 PRISM 框架创建。这是通过自动接线选项完成的。这就是外部代码。

标签: c# mvvm xamarin.forms prism prism-7


【解决方案1】:

我认为 Prism 使用类激活来创建子视图模型而不是视图模型定位器,它仅适用于页面视图模型。

但是您在内部视图中使用prism:ViewModelLocator.AutowireViewModel="True"。 所以你应该在你的 ContentPage 上使用它,然后有一个匹配的MainMenuPageViewModel,与注入的导航服务。

在这个父视图模型中,您可以创建子视图模型并传递您的依赖关系。

【讨论】:

  • ViewModelLocator 无论如何都不能用于顶级视图。如果您在视图中并且想要该视图的组件的视图模型,请从“父”视图模型创建它。不用到处先view,view model first也很有效。
  • 谢谢,我现在正在尝试。由于某种原因,没有创建 MainMenuPageViewModel。 (这是否使用正确的命名约定?)我会尝试解决这个问题,如果我不能让它工作,我会编辑我的帖子。
  • 它有效。问题是 MainMenuPage 位于名为“Pages”的命名空间中,而 PRISM 需要它位于名为“Views”的命名空间中。所以它可以工作......但现在 MainMenuView 中的命令不再调用 MainMenuViewModel 中的 ICommands 了。知道如何解决这个问题吗?
  • 如果您想要子视图模型,您需要将它们显式绑定到您的子视图。对于您的 MainMenuView,它将是这样的:&lt;views:MainMenuView BindingContext="{Binding MainMenuViewModel}" /&gt;,否则您的内容视图将仅从父视图模型继承,此处为 MainMenuPageViewModel。
  • 感谢您的帮助。我不会使用子 ViewModels
猜你喜欢
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多