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

MAUI搜索页向Grid页面传递参数的技术实现问题

MAUI参数传递+MVVM下API调用解决方案

问题背景

刚接触MAUI,之前用WinForms习惯事件驱动开发,对MAUI的DI和MVVM模式摸不清。现在要实现:搜索页拿到参数后跳转到Grid页,通过API获取对应数据并在DevExpress DataGrid展示。已经搞定API和单页功能,但搜索页的AnimalParam参数传不到Grid页,Grid页的BindingContext在API调用前拿不到参数,试过非MVVM的按钮传参也没用,求正确的传参和API调用方案。


一、页面跳转传参(两种MVVM友好的方式)

方式1:构造函数直接传参(简单直接)

先改Grid页的构造函数,让它接收AnimalParam,再把参数传给ViewModel:

public partial class grdAnimal : ContentPage
{
    public grdAnimal(AnimalParam param)
    {
        InitializeComponent();
        // 拿到ViewModel并传入参数
        var viewModel = (AnimalDataViewModel)BindingContext;
        viewModel.SearchParam = param;
        // 触发数据加载
        _ = viewModel.LoadAnimals();
    }
}

然后改搜索页的跳转代码,传参过去:

async void OnSubmitClicked(Object sender, EventArgs e)
{
    AnimalParam animalParm = new AnimalParam();
    animalParm.AnimalName = "fred";
    // 跳转时把参数传给Grid页
    await Navigation.PushModalAsync(new grdAnimal(animalParm));
}

方式2:用NavigationParameter(适合复杂场景)

如果以后要传多个参数,或者想更贴合MAUI导航规范,用这个:
搜索页跳转代码:

async void OnSubmitClicked(Object sender, EventArgs e)
{
    AnimalParam animalParm = new AnimalParam();
    animalParm.AnimalName = "fred";
    // 把参数打包进导航参数
    var navParams = new Dictionary<string, object>
    {
        {"AnimalParam", animalParm}
    };
    await Navigation.PushModalAsync(new grdAnimal(), navParams);
}

Grid页在导航完成后接收参数:

protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
    base.OnNavigatedTo(args);
    // 解析导航参数
    if (args.Parameter is Dictionary<string, object> navParams && 
        navParams.TryGetValue("AnimalParam", out var paramObj) && 
        paramObj is AnimalParam param)
    {
        var viewModel = (AnimalDataViewModel)BindingContext;
        viewModel.SearchParam = param;
        _ = viewModel.LoadAnimals();
    }
}

二、改造ViewModel,实现参数接收+异步API调用

原来的AnimalData要改成符合MVVM的ViewModel,实现INotifyPropertyChanged保证UI更新,同时把API调用改成异步(避免卡UI):

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MauiAppPagesTest.AnimalViewModel
{
    public class AnimalDataViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Animal> _animals;
        // 绑定给DataGrid的数据源
        public ObservableCollection<Animal> Animals
        {
            get => _animals;
            set
            {
                _animals = value;
                OnPropertyChanged();
            }
        }

        // 接收搜索参数
        public AnimalParam SearchParam { get; set; }

        // 异步加载数据的方法
        public async Task LoadAnimals()
        {
            // 参数为空直接返回
            if (SearchParam == null || string.IsNullOrEmpty(SearchParam.AnimalName))
                return;

            string apiUrl = "https://{你的有效API地址}/FindAnimalByName";
            IRequestHandler requestHandler = new RestSharpRequestHandler();
            // 用传入的参数调用API
            List<Animal> animalList = await requestHandler.GetAnimalByNameAsync(apiUrl, SearchParam.AnimalName);
            Animals = new ObservableCollection<Animal>(animalList);
        }

        // 实现INotifyPropertyChanged,让UI感知数据变化
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

注意:把你的GetAnimalByName改成异步方法GetAnimalByNameAsync,MAUI里不能用同步API调用阻塞UI线程。


三、调整Grid页的初始化逻辑

原来的AnimalData构造函数里自动调用GenerateAnimal的逻辑要去掉,改成通过LoadAnimals手动触发,这样就能保证参数传入后再加载数据,解决BindingContext拿不到参数的问题。

Grid页的XAML不用大改,保持原来的BindingContext配置就行:

<ContentPage.BindingContext>
    <local:AnimalDataViewModel />
</ContentPage.BindingContext>

四、DI入门(逐步过渡到MVVM规范)

如果想进一步贴合MAUI的DI规范,把IRequestHandler注册到DI容器,避免手动new:
在MauiProgram.cs里添加注册代码:

builder.Services.AddSingleton<IRequestHandler, RestSharpRequestHandler>();

然后ViewModel的构造函数改成依赖注入:

private readonly IRequestHandler _requestHandler;

// 构造函数注入IRequestHandler
public AnimalDataViewModel(IRequestHandler requestHandler)
{
    _requestHandler = requestHandler;
}

public async Task LoadAnimals()
{
    // 用注入的实例调用API
    List<Animal> animalList = await _requestHandler.GetAnimalByNameAsync(apiUrl, SearchParam.AnimalName);
    Animals = new ObservableCollection<Animal>(animalList);
}

这样代码解耦性更强,也符合MVVM的最佳实践。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:54:59