I am new to .NET MAUI and making a page "MainPage
" with flyoutPage.
In the page, I have values bounded from MainPageViewModel
and Flyout
.
When I try to set BindingContext
in MainPage.xaml.cs
, I get Flyout and Detail must be set before adding FlyoutPage to a container
error.
But if I add InitializeComponent()
to the first constructor with no parameter, it stops complaining about it.
Is keeping both of InitializeComponent()
the right way to fix this? Or am I missing something else?
In MainPage.xaml,
<?xml version="1.0" encoding="utf-8" ?>
<FlyoutPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:Realizer.ViewModels"
xmlns:models="clr-namespace:Realizer.Models"
xmlns:local="clr-namespace:Realizer.Pages"
x:Class="Realizer.Pages.MainPage"
x:DataType="vm:MainPageViewModel"
Title="Home">
<FlyoutPage.Flyout>
<ContentPage Title="Home page" BackgroundColor="LightGrey">
<VerticalStackLayout>
<CollectionView>
<CollectionView.ItemsSource>
<x:Array Type="{x:Type models:Flyout}">
<models:Flyout Title="Home"
IconSource="home.png"
Command="GoToHomePageCommand"/>
<models:Flyout Title="Clients"
IconSource="person.png"
Command="GoToClientsPageCommand"/>
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="20, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource, Source={RelativeSource AncestorType={x:Type models:Flyout}}}"
Scale="1.5"/>
<Button Grid.Column="1"
Margin="5"
Text="{Binding Title, Source={RelativeSource AncestorType={x:Type models:Flyout}}}"
Command="{Binding Command, Source={RelativeSource AncestorType={x:Type models:Flyout}}}"
FontSize="16"
FontAttributes="Bold"
TextColor="Black"
HeightRequest="60"
Padding="0,0,110,0"
BackgroundColor="LightGray"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Label Text="this is it"
Margin="20"/>
</VerticalStackLayout>
</ContentPage>
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage BarBackgroundColor="Navy"
BarTextColor="Black"
Title="Home">
<x:Arguments>
<ContentPage Title="Home" BackgroundColor="White">
<VerticalStackLayout>
<Label Text="this is detail"
Margin="20"/>
</VerticalStackLayout>
</ContentPage>
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>
In MainPage.xaml.cs
using Realizer.ViewModels;
namespace Realizer.Pages;
public partial class MainPage : FlyoutPage
{
public MainPage(){
//InitializeComponent();
}
public MainPage(MainPageViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
}
In MainPageViewModel.cs
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Realizer.Pages;
namespace Realizer.ViewModels
{
public partial class MainPageViewModel : ObservableObject
{
public MainPageViewModel()
{
}
[RelayCommand]
private async Task GoToClientsPage()
{
await Application.Current.MainPage.Navigation.PushAsync(new ClientsPage());
}
}
}
In App.xaml.cs
using Realizer.Pages;
namespace Realizer
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new MainPage();
}
}
}
When you call code
MainPage = new MainPage();
toMainPage
, it will call the default constructor(no parameter) ofMainPage
to initialize data for this page.From document Get started with XAML,we could find that :
So, we should call method
InitializeComponent()
to initialize all the objects defined in the XAML file after navigating to this page by codeMainPage = new MainPage();
. Otherwise, the code will report the error you mentioned.