App.xaml MVVM light 中的空引用错误

Null reference error in App.xaml MVVM light

我将制作一个 WPF 应用程序 window 并通过更改 Frame 的内容来导航我的应用程序。为此,我使用 MVVM light。

但是在 App.xaml 我在 Visual Studio 的错误列表中遇到了这个错误。

Object reference not set to an instance of an object.

这是发生错误的代码:

<Application 
    x:Class="Project.App" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Project" 
    StartupUri="MainWindow.xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    d1p1:Ignorable="d" 
    xmlns:vm="clr-namespace:Project.ViewModel"
    xmlns:services="clr-namespace:Project.Services"
    xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
    <Application.Resources>
        <ResourceDictionary>
            <services:IocContainer x:Key="ioc" />
            <vm:ApplicationViewModel x:Key="appvm" d:IsDataSource="True" /> <!-- error happens on this line -->
        </ResourceDictionary>
    </Application.Resources>
</Application>

这是我的 MainWindow:

<Window x:Class="Project.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Project"
        mc:Ignorable="d"
        DataContext="{StaticResource appvm}"
        Title="Project" Height="450" Width="800">
    <Frame>
        <Frame.Content>
            <Page Content="{Binding CurrentPage, Mode=TwoWay}" />
        </Frame.Content>
    </Frame>
</Window>

这是我的 ApplicationViewModel 继承自 ViewModelBase:

public class ApplicationViewModel : ViewModelBase
{
    private Page _currentPage = IocContainer.Ioc.StartScreenPage;

    public Page CurrentPage
    {
        get
        {
            return _currentPage;
        }
        set
        {
            if (_currentPage != value)
            {
                _currentPage = value;
                OnPropertyChanged();
            }
        }
    }

    public StartScreenViewModel StartScreenViewModel
    {
        get
        {
            return (App.Current.Resources["ioc"] as IocContainer)?.StartScreenViewModel;
        }
    }

    public void Navigate(Type sourcePageType)
    {
    }
}

这是实现 INotifyPropertyChangedViewModelBase

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            Debug.WriteLine("PropertyChanged is niet null ☺");
        }
        else
        {
            Debug.WriteLine("PropertyChanged is null");
        }
    }
}

这是我的 IoC 容器:

public class IocContainer
{
    static IocContainer()
    {
        SimpleIoc.Default.Register<ApplicationViewModel>(false);
        SimpleIoc.Default.Register<StartScreenViewModel>(false);
        SimpleIoc.Default.Register<StartScreenPage>(false);
    }

    public static IocContainer Ioc
    {
        get { return App.Current.Resources["ioc"] as IocContainer; }
    }

    public ApplicationViewModel ApplicationViewModel
    {
        get { return SimpleIoc.Default.GetInstance<ApplicationViewModel>(); }
    }

    public StartScreenPage StartScreenPage
    {
        get { return SimpleIoc.Default.GetInstance<StartScreenPage>(); }
    }

    public StartScreenViewModel StartScreenViewModel
    {
        get { return SimpleIoc.Default.GetInstance<StartScreenViewModel>(); }
    }
}

这是我的 StartScreenPage:

<Page x:Class="Project.StartScreenPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:Project"
      mc:Ignorable="d" 
      DataContext="{Binding StartScreenViewModel, Source={StaticResource ioc}}"
      Title="StartScreen">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto" />
        </Grid.ColumnDefinitions>

        <Label Content="Hello world" Grid.Row="0" Grid.Column="0" />
    </Grid>
</Page>

这里是 StartScreenViewModel

public class StartScreenViewModel : ViewModelBase
{ }

所有应用程序、window 和页面都有一个调用 InitializeComponent 的默认构造函数。

我可以 运行 我的应用程序,但我看到一个空的 window。

我是不是忘记了什么?

编辑: 继续我对这个问题的回答:Page can have only Frame as parent and not Window,我已经将 MainWindow 的代码更改为:

The code on the MainWindow must be this:

<!-- Opening Window tag with all attributes -->
<Frame Content="{Binding CurrentPage, Mode=TwoWay}" />
<!-- Closing Window tag -->

This will also show the StartScreenPage on the window.

然而空引用错误仍然被抛出。

您的代码中很少进行空值检查,而这正是发生这种情况的地方。

查找问题的最佳方法是转到 Visual Studio 工具面板

调试→Windows→异常设置

并完全检查标记为“Common Language Runtime Exceptions”的行。当您再次 运行 代码时,您应该获得有关空异常发生位置的更多信息。