使用 CommunityToolkit.MVVM 将参数从 ViewModel 传递到 .NET MAUI 中的 ViewModel

Tan*_*ere 2 maui .net-maui

我的接收 Viewmodel (QuestionsPageViewModel) 在通过 Shell 导航传递 TopidId 后未收到 TopidId,如下面的代码所示。我已将断点放置在 QuestionsPageViewModel 中的 LoadQuestions 方法处。调用时TopicId为null。我缺少什么?

主页视图模型

//This is in a command executed after clicking a button. And this is working fine
await Shell.Current.GoToAsync($"{nameof(QuestionsPage)}?TopicId={pack.TopicId}");
Run Code Online (Sandbox Code Playgroud)

问题页面视图模型

[INotifyPropertyChanged]
[QueryProperty(nameof(TopicId), nameof(TopicId))]
    public partial class QuestionsPageViewModel
    {
        public ObservableRangeCollection<Question> QuestionsList { get; set; } = new();
        [ObservableProperty]
        string? title;

        [ObservableProperty]
        public string topicId;

        public QuestionsPageViewModel()
        {
            LoadQuestions();
        }

        async void LoadQuestions()
        {
            Title = Utilities.ConvertTopicIdToString(short.Parse(TopicId));

            try
            {
                using (var context = new DataContext())
                {
                    QuestionPack questionPack = context.QuestionPacks
                        .First(x => x.TopicId == short.Parse(TopicId));

                    var questions = JsonConvert.DeserializeObject<List<Question>>(questionPack.Questions);
                    QuestionsList.AddRange(questions);
                }

            }
            catch (Exception ex)
            {
                await Shell.Current.DisplayAlert("Error", $"Something went wrong: {ex}", "Cancel");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*ato 6

首先,你的领域topicId应该是私有的。CommumityToolkit.Mvvm 将为您生成公共属性。

其次,topicIdnull因为您正在构造函数中调用的函数中检查其值。当您执行构造函数时,shell 导航参数尚未初始化。

如果您想确保在初始化LoadQuestions()后调用topicId该方法,自版本 8.0.0 起 CommumityToolkit.Mvvm 应该生成一个部分方法,可用于在更改ObservableProperty其值后执行一些代码。在您的情况下,此方法的名称应该是OnTopicIdChanged(string value).

尝试在视图模型中添加此方法并从构造函数中删除函数调用:

partial void OnTopicIdChanged(string value)
{
    LoadQuestions();
}
Run Code Online (Sandbox Code Playgroud)