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

.NET MAUI页面导航:如何传递参数至目标页面

问题描述

我正尝试从ViewModel中传递部分属性至另一个页面,以便后续在UI端进行数据绑定。以下是我的QuizDisplayViewModel逻辑代码,我希望将其中的Score、TotalCorrectAnswers、总答题数属性传递至LoadingQuiz页面:

[QueryProperty(nameof(QuizId),nameof(QuizId))]
public partial class QuizDisplayViewModel : BaseViewModel
{          
    public ObservableCollection<QuestionVM> QuestionsVM { get; } = new();
    QuizDisplayService quizDisplayService;
    private readonly IMapper _mapper;
    private int _currentQuestionIndex;
    private int _totalQuestionsNumber;

    public int QuizId { get; set; }

    private bool isLoading;
    public bool IsLoading
    {
        get => isLoading;
        set => SetProperty(ref isLoading, value);
    }
   
    public int CurrentQuestionIndex
    {
        get => _currentQuestionIndex;
        set => SetProperty(ref _currentQuestionIndex, value);
    }
    public int TotalQuestionsNumber
    {
        get => _totalQuestionsNumber;
        set => SetProperty(ref _totalQuestionsNumber, value);
    }
    private bool _isOptionSelected;
    public bool IsOptionSelected
    {
        get => _isOptionSelected;
        set
        {
            _isOptionSelected = value;
            OnPropertyChanged(nameof(IsOptionSelected));
        }
    }

    private int _totalCorrectAnswers;
    public int TotalCorrectAnswers
    {
        get => _totalCorrectAnswers;
        set => SetProperty(ref _totalCorrectAnswers, value);
    }

    private double _score;
    public double Score
    {
        get => _score;
        set => SetProperty(ref _score, value);
    }

    [RelayCommand]
    public void Proceed()
    {
        // Get the current question
        QuestionVM currentQuestion = QuestionsVM[CurrentQuestionIndex];

        // Check if the user has selected a correct answer
        if (currentQuestion.Options.Any(o => o.IsSelected && o.IsCorrect))
        {
            TotalCorrectAnswers++;
        }

        // Hide the current question
        currentQuestion.IsVisible = false;

        // If there is another question, show it
        if (CurrentQuestionIndex < QuestionsVM.Count - 1)
        {
            CurrentQuestionIndex++;
            QuestionsVM[CurrentQuestionIndex].IsVisible = true;
        }
        else // No more questions, go to QuizSummary
        {
            Score = (TotalCorrectAnswers / (double)QuestionsVM.Count) * 100;
            Shell.Current.GoToAsync(nameof(LoadingQuiz));
        }
    }
}
解决方法

通过Shell导航的查询参数就能实现属性传递,分三步操作:

1. 修改导航代码,携带参数

把Proceed方法改成异步(因为GoToAsync是异步方法),并在导航时附加需要传递的参数:

[RelayCommand]
public async Task Proceed()
{
    // 原有逻辑不变...
    else // No more questions, go to LoadingQuiz
    {
        Score = (TotalCorrectAnswers / (double)QuestionsVM.Count) * 100;
        // 组装参数字典,总答题数可根据需求选QuestionsVM.Count或TotalQuestionsNumber
        var navParams = new Dictionary<string, object>
        {
            { "Score", Score },
            { "TotalCorrectAnswers", TotalCorrectAnswers },
            { "TotalQuestionsCount", QuestionsVM.Count }
        };
        await Shell.Current.GoToAsync(nameof(LoadingQuiz), navParams);
    }
}

2. 在LoadingQuiz的ViewModel中接收参数

给LoadingQuiz对应的ViewModel添加[QueryProperty]特性,匹配传递时的参数键名:

public partial class LoadingQuizViewModel : BaseViewModel
{
    [QueryProperty(nameof(Score), "Score")]
    private double _score;
    public double Score
    {
        get => _score;
        set => SetProperty(ref _score, value);
    }

    [QueryProperty(nameof(TotalCorrectAnswers), "TotalCorrectAnswers")]
    private int _totalCorrectAnswers;
    public int TotalCorrectAnswers
    {
        get => _totalCorrectAnswers;
        set => SetProperty(ref _totalCorrectAnswers, value);
    }

    [QueryProperty(nameof(TotalQuestionsCount), "TotalQuestionsCount")]
    private int _totalQuestionsCount;
    public int TotalQuestionsCount
    {
        get => _totalQuestionsCount;
        set => SetProperty(ref _totalQuestionsCount, value);
    }

    // 其他ViewModel逻辑...
}

3. UI端直接绑定属性

现在可以在LoadingQuiz的XAML中直接绑定这些属性:

<StackLayout>
    <Label Text="最终得分: {Binding Score:F1}" />
    <Label Text="答对题数: {Binding TotalCorrectAnswers}" />
    <Label Text="总答题数: {Binding TotalQuestionsCount}" />
</StackLayout>

注意事项

  • 参数名称大小写敏感,传递和接收的键名必须完全一致
  • 如果你的TotalQuestionsNumber已经正确赋值为总题数,可直接替换QuestionsVM.Count传递
  • 基础类型(数字、字符串等)可直接传递,复杂类型需要额外序列化处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:32:16