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

.NET MAUI依赖注入问题:ViewModel构造函数未被调用

问题:MAUI通用弹窗ViewModel构造函数未执行

问题描述

实现可复用的通用弹窗,已在MauiProgram.cs中正确注册ViewModel,调用逻辑无误,但ViewModel的构造函数始终未执行。弹窗可正常显示,但因构造函数未执行,无法加载预设的赋值内容。

补充:直接将BaitPickerViewModel传入PickerBottomSheet可正常工作,但会失去弹窗复用性;传入抽象类PickerBottomSheetViewModel不可行。


核心代码

依赖注入注册代码

builder.Services.AddTransientPopup<PickerBottomSheet, BaitPickerViewModel>();

通用调用方法

public async Task<TItem?> DisplayBottomPickerAsync<TViewModel, TItem>(CancellationToken token = default)
    where TViewModel : PickerBottomSheetViewModel<TItem>
    where TItem : IPickableItem
{
    var result = await _popup.ShowPopupAsync<TViewModel, TItem>(Shell.Current, GetOptions(true), token);
    return result.WasDismissedByTappingOutsideOfPopup ? default : result.Result;
}

调用代码

var result = await _popup.DisplayBottomPickerAsync<BaitPickerViewModel, Bait>(token);

ViewModel继承结构核心代码

public abstract partial class PickerBottomSheetViewModel : ViewModelBase

public abstract partial class PickerBottomSheetViewModel<T> : PickerBottomSheetViewModel where T : IPickableItem

public sealed partial class BaitPickerViewModel : PickerBottomSheetViewModel<Bait>
{
    private readonly SqliteStorage _sql;
    private readonly ILocalizationResourceManager _lang;

    public BaitPickerViewModel(PopupHost popup, SqliteStorage sql, ILocalizationResourceManager lang) : base(popup)
    {
        _sql = sql; //从未被执行
        _lang = lang;

        Title = _lang["SelectBaitTitle"];
        AddNewText = _lang["AddNewBait"];
        CanEditOrDelete = true;
    }

    protected override IAsyncEnumerable<Bait> LoadTypedItemsAsync(CancellationToken token) => _sql.EnumerateBaitsAsync(token);
    protected override Task<Bait?> AddTypedItemAsync(CancellationToken token) => base.AddTypedItemAsync(token);
    protected override Task<Bait?> EditTypedItemAsync(Bait item, CancellationToken token) => base.EditTypedItemAsync(item, token);
    protected override Task DeleteTypedItemAsync(Bait item, CancellationToken token) => base.DeleteTypedItemAsync(item, token);
}

弹窗代码

C#代码

public sealed partial class PickerBottomSheet : Popup<IPickableItem>
{
    public PickerBottomSheet()
    {
        InitializeComponent();
    }
}

XAML代码

<mct:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
           xmlns:icon="http://www.aathifmahir.com/dotnet/2022/maui/icons"
           xmlns:lang="clr-namespace:LocalizationResourceManager.Maui;assembly=LocalizationResourceManager.Maui"
           xmlns:common="clr-namespace:CatchLog.Common"
           xmlns:models="clr-namespace:CatchLog.Models"
           xmlns:viewmodels="clr-namespace:CatchLog.ViewModels.Popups"
           x:Class="CatchLog.Popups.PickerBottomSheet"
           x:DataType="viewmodels:PickerBottomSheetViewModel"
           x:TypeArguments="models:IPickableItem"
           Background="{mct:AppThemeResource Surface}"
           HorizontalOptions="Fill"
           VerticalOptions="End">

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 16:19:50