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)
{
}
}
这是实现 INotifyPropertyChanged
的 ViewModelBase
。
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
”的行。当您再次 运行 代码时,您应该获得有关空异常发生位置的更多信息。
我将制作一个 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)
{
}
}
这是实现 INotifyPropertyChanged
的 ViewModelBase
。
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
”的行。当您再次 运行 代码时,您应该获得有关空异常发生位置的更多信息。