我有两个ViewModel:MainViewModel和QuestionViewModel。我在ViewModelLocator中注册它们。

SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<QuestionViewModel>();

在MainViewModel上,我有一个带问题的ListBox。单击时,我执行此命令
NavigationService.NavigateTo(new Uri("/Pages/QuestionPage.xaml", UriKind.Relative));
Messenger.Default.Send<Question, QuestionViewModel>(q);

QuestionPage的DataContext设置为QuestionViewModel。在QuestionViewModel上,我注册消息:
Messenger.Default.Register<Question>(this, q =>
{
    MessageBox.Show("!");
});

但是此函数仅在QuestionViewModel的第二次打开时起作用,因为QuestionViewModel实例仅在第一次打开时创建。我的问题是:我需要在何时何地在MVVM Light中创建QuestionViewModel的实例?我不想在启动时创建所有页面。

现在,我在构造函数ViewModelLocator中创建实例:
public ViewModelLocator()
{
    ServiceLocator.Current.GetInstance<QuestionViewModel>();
}

这是好习惯吗?

最佳答案

没错,这不是在ViewModelLocator构造函数中创建所有 View 模型的好习惯。您收到此问题的原因是在发送消息后创建了QuestionViewModel。您可以尝试创建一个共享当前Question对象的服务,并将该服务注入(inject)MainViewModelQuestionViewModel

public interface IQuestionService
{
    Question CurrentQuestion {get; set;}
}

public class QuestionService : IQuestionService
{
    public Question CurrentQuestion {get; set;}
}

然后在Click中的MainViewModel上保存当前问题:
_questionService.CurrentQuestion = q;

并在你的QuestionViewModel中使用

只需确保将相同的IQuestionService实例注入(inject) View 模型即可。

另一种变体是在URL中传递简单的导航参数,如下所示:
NavigationService.NavigateTo(new Uri("/Pages/QuestionPage.xaml?questionid=" + q.Id, UriKind.Relative));

另外,您可以尝试实现自己的NavigationService,该服务支持传递参数,但这更加复杂。

10-08 15:52