I’m developing an app using MAUI. I have four pages that are virtually identical. On the fourth, I always get NULL for the model being passed from the view. I’ve tried every number of things, from creating another page to copy and pasting a working page into the XAML and C#. I know it is probably something simple, but it is eluding me.
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:models="clr-namespace:WhatGoesIn.Models"
x:Class="WhatGoesIn.Views.ExportPage"
xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
ios:Page.UseSafeArea="True"
Title="Export">
<ContentPage.BindingContext>
<models:ExportItem />
</ContentPage.BindingContext>
<ScrollView>
<VerticalStackLayout
Padding="20"
Spacing="10"
VerticalOptions="StartAndExpand">
<Label Text="Date" FontAttributes="Bold"/>
<DatePicker Date="{Binding StartDate}" MinimumDate="01/01/2023"/>
<Label Text="Time" FontAttributes="Bold"/>
<DatePicker Date="{Binding ToDate}"/>
<Label Text="Recipient" FontAttributes="Bold" FontSize="16"/>
<Entry Text="{Binding Recipient}" />
<Button Text="Export" Clicked="OnExportClicked" />
<Button Text="Cancel"
Clicked="OnCancelClicked" />
</VerticalStackLayout>
</ScrollView>
</ContentPage>
C#
using WhatGoesIn.Models;
namespace WhatGoesIn.Views;
[QueryProperty("Item", "Item")]
public partial class ExportPage : ContentPage
{
WhatGoesInDatabase database;
public ExportItem Item
{
get => BindingContext as ExportItem;
set => BindingContext = value;
}
public ExportPage(WhatGoesInDatabase whatGoesInDatabase)
{
InitializeComponent();
BindingContext = this;
database = whatGoesInDatabase;
}
private async void OnExportClicked(object sender, EventArgs e)
{
ExportItem item = Item as ExportItem; // <= always NULL!
string body = await database.ExportItemAsync(item);
if (string.IsNullOrEmpty(Item.Recipient))
{
await DisplayAlert("No Recipient", "Please choose the recipient of the report.", "OK");
return;
}
if (Email.Default.IsComposeSupported)
{
string subject = "What Goes In Food Log!";
string[] recipients = new[] { Item.Recipient };
var message = new EmailMessage
{
Subject = subject,
Body = body,
BodyFormat = EmailBodyFormat.PlainText,
To = new List<string>(recipients)
};
await Email.Default.ComposeAsync(message);
}
await Shell.Current.GoToAsync("..");
}
private async void OnCancelClicked(object sender, EventArgs e)
{
await Shell.Current.GoToAsync("..");
}
}
Model
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WhatGoesIn.Models
{
public class ExportItem
{
[PrimaryKey, AutoIncrement]
public long ID { get; set; }
public DateTime StartDate { get; set; }
public DateTime ToDate { get; set; }
public string Recipient { get; set; }
}
}
>Solution :
It seems like the issue is that the Item property is not being set properly. The XAML is already setting the BindingContext for the ContentPage, and you are trying to set the BindingContext again. This is causing the BindingContext to be overwritten and the Item is not being initialized correctly.
Looks like you need to remove this line from the ExportPage constructor:
BindingContext = this;