You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将SQLite注入MAUI ViewModel时出现无参构造函数报错

MAUI构造函数注入ViewModel报错解决

问题

我是MAUI新手,现有一个基于SQLite存储的正常运行项目。尝试将数据库访问对象注入Content Page的ViewModel时,出现如下报错:

/Users/RemoteCommand/Projects/Notes/Views/AllNotesPage.xaml(9,9): Error: XLS0507: Type 'AllNotes' is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter. (Notes) IntelliSense

此前直接实例化数据库访问对象可正常运行,改为构造函数注入后出现该问题。已在MauiProgram中注册AllNotes、AllNotesPage和NotesDatabase为单例服务,也尝试过改为Transient,问题仍未解决。

相关代码

AllNotesPage.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:Notes.Models"
             x:Class="Notes.Views.AllNotesPage"
             Title="AllNotesPage">

    <ContentPage.BindingContext>
        <models:AllNotes />
    </ContentPage.BindingContext>

    <ContentPage.ToolbarItems>
        <!--<ToolbarItem Text="Add" Clicked="Add_Clicked" IconImageSource="{FontImage Glyph='+', Color=White, Size=22}"/>-->
        <ToolbarItem Text="Add" Command="{Binding AddClickedCommand}" IconImageSource="{FontImage Glyph='+', Color=White, Size=22}"/>
    </ContentPage.ToolbarItems>

    <CollectionView x:Name="notesCollection"
                    ItemsSource="{Binding Notes}"
                    Margin="20"
                    SelectionMode="Single"
                    SelectionChanged="notesCollection_SelectionChanged">

        <CollectionView.ItemsLayout>
            <LinearItemsLayout Orientation="Vertical" ItemSpacing="10"/>
        </CollectionView.ItemsLayout>

        <CollectionView.ItemTemplate>
            <DataTemplate>
                <StackLayout>
                    <Label Text="{Binding Text}" FontSize = "22"/>
                    <Label Text="{Binding Date}" FontSize="14" TextColor="Silver"/>
                </StackLayout>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

AllNotesPage.xaml.cs

namespace Notes.Views;
using Notes.Models;
using Notes.Views;
using Notes.Data;
using CommunityToolkit.Mvvm.Input;

public partial class AllNotesPage : ContentPage
{   
    public AllNotesPage()
    {
        InitializeComponent();
    }
    async void notesCollection_SelectionChanged(System.Object sender, Microsoft.Maui.Controls.SelectionChangedEventArgs e)
    {
        if(e.CurrentSelection.Count != 0)
        {
            var note = (Note)e.CurrentSelection[0];
            await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)}={note.ID}");
        }
    }
}

AllNotes.cs(ViewModel)

using System;
using System.Collections.ObjectModel;
using Notes.Data;
using Notes.Views;
using CommunityToolkit.Mvvm;
using CommunityToolkit.Mvvm.Input;

namespace Notes.Models;

public partial class AllNotes
{
    NotesDatabase _notesDatabase;

    public ObservableCollection<Note> Notes { get; set; } = new ObservableCollection<Note>();

    public AllNotes(NotesDatabase notesDatabase)
    {
        _notesDatabase = notesDatabase;
        LoadNotes();
    }
    [RelayCommand]
    async void AddClicked()
    {
        await Shell.Current.GoToAsync(nameof(NotePage));
    }
    public async void LoadNotes()
    {
        Notes.Clear();
        List<Note> notes = await _notesDatabase.GetItemsAsync();
        foreach(Note note in notes)
        {
            Notes.Add(note);
        }
    }
}

MauiProgram.cs

using Microsoft.Extensions.Logging;
using Notes.Views;
using Notes.Models;
using Notes.Data;

namespace Notes;

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");
            });

#if DEBUG
        builder.Logging.AddDebug();
#endif

        builder.Services.AddSingleton<AllNotes>();
        builder.Services.AddSingleton<AllNotesPage>();
        builder.Services.AddSingleton<NotesDatabase>();
        
        return builder.Build();
    }
}

解决方法

报错核心原因:你在XAML中直接实例化AllNotes,但该ViewModel只有带参数的构造函数,XAML无法创建需要依赖注入的对象实例。按以下步骤修改:

  1. 删除XAML中的硬编码BindingContext
    移除XAML里这段代码:

    <ContentPage.BindingContext>
        <models:AllNotes />
    </ContentPage.BindingContext>
    
  2. 通过构造函数注入ViewModel到页面
    修改AllNotesPage的后台代码,注入AllNotes并设置为BindingContext:

    namespace Notes.Views;
    using Notes.Models;
    using Notes.Data;
    using CommunityToolkit.Mvvm.Input;
    
    public partial class AllNotesPage : ContentPage
    {   
        public AllNotesPage(AllNotes viewModel)
        {
            InitializeComponent();
            BindingContext = viewModel;
        }
        async void notesCollection_SelectionChanged(System.Object sender, Microsoft.Maui.Controls.SelectionChangedEventArgs e)
        {
            if(e.CurrentSelection.Count != 0)
            {
                var note = (Note)e.CurrentSelection[0];
                await Shell.Current.GoToAsync($"{nameof(NotePage)}?{nameof(NotePage.ItemId)}={note.ID}");
            }
        }
    }
    
  3. 保持服务注册不变
    你已在MauiProgram中正确注册了所有服务,无需修改:

    builder.Services.AddSingleton<AllNotes>();
    builder.Services.AddSingleton<AllNotesPage>();
    builder.Services.AddSingleton<NotesDatabase>();
    

修改后,MAUI的依赖注入系统会自动处理对象创建和依赖注入,问题即可解决。

内容的提问来源于stack exchange,提问作者David Pugh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 17:50:43