我正在构建一个无线电应用程序,其中包含NavigationView
与一个页面(现在),这将是ExploreCountriesPage
,但我有问题实现这一点。MainWindow.xaml
是主窗口,真正应该处理导航,并应显示在frame
元素的子页面的内容。不幸的是,当我试图在MainWindow.xaml的框架中显示ExploreCountriesPage
时,我得到Object reference not set to an instance of an object错误。
最终,我想实现的是在主窗口的框架内显示页面,并在页面显示时立即获取数据。
我怎么才能做到这一点?我做错了什么?
App.cs
public partial class App : Application
{
public IServiceProvider Container { get; private set; }
public App()
{
this.InitializeComponent();
}
private IServiceProvider RegisterServices()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<IRadioBrowserClient>(new RadioBrowserClient(apiUrl: "de1.api.radio-browser.info"));
serviceCollection.AddSingleton<ExploreCountriesViewModel>();
return serviceCollection.BuildServiceProvider();
}
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
Container = RegisterServices();
m_window = new MainWindow();
m_window.Activate();
}
private Window m_window;
}
MainWindow.cs
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
ContentFrame.Navigate(typeof(ExploreCountriesPage)); // <-- this line causes the error
}
}
MainWindow.xaml
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="Rad.io.Client.WinUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Rad.io.Client.WinUI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:views="using:Rad.io.Client.WinUI.Views">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid x:Name="AppTitleBar">
<Image Source="Images/WindowIcon.png"
HorizontalAlignment="Left"
Width="16" Height="16"
Margin="8,0"/>
<TextBlock x:Name="AppTitleTextBlock" Text="Rad.io"
TextWrapping="NoWrap"
Style="{StaticResource CaptionTextBlockStyle}"
VerticalAlignment="Center"
Margin="28,0,0,0"/>
</Grid>
<NavigationView x:Name="NavigationView"
SelectionChanged="NavigationView_SelectionChanged"
Header="Explore"
Grid.Row="1"
IsBackButtonVisible="Collapsed"
IsSettingsVisible="True">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Globe" Content="Explore" Tag="Explore" />
<NavigationViewItem Icon="Library" Content="Library" Tag="SamplePage2" />
<NavigationViewItem Icon="Play" Content="Now Playing" Tag="SamplePage3" />
</NavigationView.MenuItems>
<Frame x:Name="ContentFrame"/>
</NavigationView>
</Grid>
</Window>
ExploreCountriesViewModel.cs
namespace Rad.io.Client.WinUI.ViewModels
{
public class ExploreCountriesViewModel : INotifyPropertyChanged
{
private readonly IRadioBrowserClient radioBrowserClient;
private List<NameAndCount> _countries;
private List<NameAndCount> filteredCountries;
private string entryQuery;
public List<NameAndCount> Countries
{
get => _countries;
set
{
_countries = value;
RaisePropertyChanged();
}
}
public List<NameAndCount> FilteredCountries
{
get
{
if (EntryQuery is null) return Countries;
return Countries.Where(value => value.Name.Contains(EntryQuery, StringComparison.OrdinalIgnoreCase)).ToList();
}
}
public string EntryQuery
{
get => entryQuery;
set
{
entryQuery = value;
RaisePropertyChanged();
}
}
public ExploreCountriesViewModel(IRadioBrowserClient radioBrowserClient)
{
this.radioBrowserClient = radioBrowserClient;
InitializeDataAsync();
}
public async Task InitializeDataAsync()
{
try
{
Countries = await radioBrowserClient.Lists.GetCountriesAsync();
foreach (var result in Countries)
{
Debug.WriteLine(result.Name);
}
}
catch (Exception e)
{
Debug.WriteLine(e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
ExploreCountriesPage.cs
public sealed partial class ExploreCountriesPage : Page
{
public ExploreCountriesViewModel CountriesViewModel { get; set; }
public ExploreCountriesPage(ExploreCountriesViewModel exploreCountriesViewModel)
{
this.InitializeComponent();
this.CountriesViewModel = exploreCountriesViewModel;
DataContext = CountriesViewModel;
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
await CountriesViewModel.InitializeDataAsync();
}
}
ExploreCountriesPage.xaml
<Page
x:Class="Rad.io.Client.WinUI.Views.ExploreCountriesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Rad.io.Client.WinUI.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<TextBlock Text="Content"
Style="{ThemeResource TitleTextBlockStyle}"
Margin="32,0,0,0"/>
<ListView BorderThickness="1"
ItemsSource="{x:Bind CountriesViewModel.FilteredCountries}"
BorderBrush="{ThemeResource SystemControlForegroundBaseMediumLowBrush}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</StackPanel>
</Page>
1条答案
按热度按时间6tqwzwtp1#
我猜你得到的错误,因为服务提供商,它不负责示例化ExploreCountiresPage。
上面的导航需要一个无参数的构造函数。
一种方法是使用类似this的代码,并在构造函数中获取ViewModel。