.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
相关产品推荐
相关产品推荐

