I am creating my first MAUI app that is a term tracker (With community toolkit MVVM). I've added a few terms manually to the database, and I am trying to get them to display in a fly out. I have been able to get them to show up in the fly out, but I'm having trouble getting the term name to databind and I am getting an error:
Binding:Property "Name" not found on TermTracker.ViewModel.TermViewModel
Here's all my relevant files.
The term model using SQLite.
using SQLite;
namespace TermTracker.Model;
[Table("Terms")]
public class Term
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string? Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
Getting the terms and putting term models in an ObservableCollection and returning it
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
namespace TermTracker.Model
{
public static class TermRepository
{
public static async Task<ObservableCollection<Term>> GetTerms()
{
var db = LocalDatabase.GetConnection();
var terms = new ObservableCollection<Term>();
var queryResult = await db.QueryAsync<Term>("SELECT * FROM Terms");
foreach (var term in queryResult)
{
terms.Add(new Term
{
Name = term.Name,
StartDate = term.StartDate,
EndDate = term.EndDate
});
}
return terms;
}
}
}
Adding the relevant items for DI
using Microsoft.Extensions.Logging;
using TermTracker.Model;
using TermTracker.View;
using TermTracker.ViewModel;
namespace TermTracker
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
builder.Services.AddTransient<AppShell>();
builder.Services.AddTransient<TermViewModel>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
}
Setting the binding context to be the TermViewModel
using TermTracker.Model;
using TermTracker.View;
using TermTracker.ViewModel;
namespace TermTracker
{
public partial class AppShell : Shell
{
public AppShell(TermViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
Routing.RegisterRoute(nameof(AddTermPage), typeof(AddTermPage));
}
}
}
Adding the view model, datatype, and setting up my flyout menu.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="TermTracker.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TermTracker"
xmlns:view="clr-namespace:TermTracker.View"
xmlns:viewModel="clr-namespace:TermTracker.ViewModel"
x:DataType="viewModel:TermViewModel"
Shell.FlyoutBehavior="Flyout"
Title="TermTracker">
<Shell.Resources>
<DataTemplate x:Key="FlyoutTermTemplate">
<TextCell Text="{Binding Name}"/>
This is where the problem is. Terms.Name doesn't work either. I want the text of the flyout item to be the name of the term model in the observable collection.
Oddly, when I do Binding Name when the app is running and it hotloads, it works but when I stop/try to restart my app I get the error.
</DataTemplate>
</Shell.Resources>
<Shell.FlyoutContentTemplate>
<DataTemplate>
<ListView
ItemsSource="{Binding Terms}"
ItemTemplate="{StaticResource FlyoutTermTemplate}"/>
</DataTemplate>
</Shell.FlyoutContentTemplate>
<ShellContent Title="Home"
ContentTemplate="{DataTemplate view:MainPage}"
Route="MainPage"/>
</Shell>
Thanks for taking a look at my problem. This is my first post!
I tried setting relative paths, ancestors, tried accessing the terms properties in the observable collection. Can't seem to get it to work.
You can try to set the x:DataType
for the DataTemplate. Such as:
<Shell
x:Class="TermTracker.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TermTracker"
xmlns:view="clr-namespace:TermTracker.View"
xmlns:model="clr-namespace:TermTracker.Model"
xmlns:viewModel="clr-namespace:TermTracker.ViewModel"
x:DataType="viewModel:TermViewModel"
Shell.FlyoutBehavior="Flyout"
Title="TermTracker">
<Shell.Resources>
<DataTemplate x:DataType="model:Term" x:Key="FlyoutTermTemplate">
<TextCell Text="{Binding Name}"/>