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

使用IPopupService自定义弹窗时出现KeyNotFoundException错误求助

问题原因及解决方案

核心问题

你遇到的KeyNotFoundException是因为依赖注入注册错误,以及ShowPopupAsync的用法与服务配置不匹配:

  • 错误的注册方式AddTransient<SimplePopup, SimplePopupViewModel>()把弹窗页面和ViewModel错误映射,导致PopupService找不到对应的ViewModel关联弹窗
  • 弹窗未正确绑定ViewModel,也未实现返回值逻辑

步骤1:修复依赖注入注册

修改MauiProgram.cs中的服务注册代码,将错误映射替换为分别注册弹窗和ViewModel:

// 替换原来的错误注册行
builder.Services.AddTransient<SimplePopup>();
builder.Services.AddTransient<SimplePopupViewModel>();

如果要使用ShowPopupAsync<TViewModel>泛型方法,需额外添加弹窗与ViewModel的接口绑定:

// 让PopupService能通过ViewModel找到对应的弹窗
builder.Services.AddTransient<IPopup<SimplePopupViewModel>, SimplePopup>();

步骤2:完善弹窗的ViewModel绑定与返回值逻辑

修改弹窗后台代码(SimplePopup.xaml.cs)

添加构造函数注入ViewModel,并实现按钮点击返回结果的逻辑:

using CommunityToolkit.Maui.Views;
using SimplePopup.ViewModel;

namespace SimplePopup;

public partial class SimplePopup : Popup
{
    public SimplePopup(SimplePopupViewModel viewModel)
    {
        InitializeComponent();
        BindingContext = viewModel; // 绑定ViewModel到弹窗
    }

    // Yes按钮点击事件,返回true表示确认
    private void YesButton_Clicked(object sender, EventArgs e)
    {
        Close(true);
    }

    // No按钮点击事件,返回false表示取消
    private void NoButton_Clicked(object sender, EventArgs e)
    {
        Close(false);
    }
}

修改弹窗XAML代码

给按钮添加点击事件绑定:

<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup
    x:Class="SimplePopup.SimplePopup"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:viewModel="clr-namespace:SimplePopup.ViewModel"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
    
    <VerticalStackLayout>
        <Label
            HorizontalOptions="Center"
            Text="{Binding Name}"
            VerticalOptions="Center" />

        <Button Text="Yes" Clicked="YesButton_Clicked" />
        <Button Text="No" Clicked="NoButton_Clicked" />

    </VerticalStackLayout>
</toolkit:Popup>

步骤3:修正弹窗调用代码

方式1:直接实例化弹窗(直观易调试)

private readonly IServiceProvider _serviceProvider;
private readonly IPopupService _popupService;

// 通过构造函数注入所需服务
public MainPage(IServiceProvider serviceProvider, IPopupService popupService)
{
    InitializeComponent();
    _serviceProvider = serviceProvider;
    _popupService = popupService;
}

private async void Button_Clicked(object sender, EventArgs e)
{
    try
    {
        // 获取ViewModel并设置展示数据
        var popupVm = _serviceProvider.GetRequiredService<SimplePopupViewModel>();
        popupVm.Name = "John Smith";
        
        // 创建弹窗实例并弹出
        var popup = new SimplePopup(popupVm);
        var result = await _popupService.ShowPopupAsync(popup);
        
        // 处理用户返回结果
        if (result is bool isConfirmed)
        {
            Console.WriteLine(isConfirmed ? "用户确认操作" : "用户取消操作");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

方式2:使用泛型ShowPopupAsync<TViewModel>(需步骤1的接口绑定)

private async void Button_Clicked(object sender, EventArgs e)
{
    try
    {
        // 自动创建ViewModel和弹窗,设置数据并获取返回结果
        var result = await _popupService.ShowPopupAsync<SimplePopupViewModel>(viewModel => viewModel.Name = "John Smith");
        
        if (result is bool isConfirmed)
        {
            Console.WriteLine(isConfirmed ? "用户确认操作" : "用户取消操作");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:06:06