本文介绍了ViewModel在MVVM Light中未收到消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two ViewModels: MainViewModel and QuestionViewModel. I Register they in ViewModelLocator.

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

在MainViewModel上,我有一个带问题的列表框.当我单击时,执行此命令

On MainViewModel I have a ListBox with Questions. When Click I execute this command

NavigationService.NavigateTo(new Uri("/Pages/QuestionPage.xaml", UriKind.Relative));
Messenger.Default.Send<Question, QuestionViewModel>(q);

QuestionPage的DataContext设置为QuestionViewModel.在QuestionViewModel上,我注册消息:

QuestionPage's DataContext set to QuestionViewModel. On QuestionViewModel I register message:

Messenger.Default.Register<Question>(this, q =>
{
    MessageBox.Show("!");
});

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

But this function work only on second open of QuestionViewModel, because QuestionViewModel instance creates only on first opening. My Question is: Where and When I need to create instance of QuestionViewModel in MVVM Light? I dont want create all my pages at startup.

现在,我在构造函数ViewModelLocator中创建实例:

Now, I create instance in constructor ViewModelLocator:

public ViewModelLocator()
{
    ServiceLocator.Current.GetInstance<QuestionViewModel>();
}

这是一个好习惯吗?

推荐答案

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

You're right, this is not a good practice to create all view models in ViewModelLocator constructor. The reason of the issue you got is that QuestionViewModel is created after you send the message. You can try to create a service which will share current Question object and inject this service into MainViewModel and QuestionViewModel.

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

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

然后在MainViewModel中的Click上保存当前问题:

Then on Click in MainViewModel just save current question:

_questionService.CurrentQuestion = q;

并在QuestionViewModel

只需确保将相同的IQuestionService实例注入视图模型即可.

Just make sure you inject the same instance of IQuestionService into your view models.

另一种变体是在这样的URL中传递简单的导航参数:

One more variant is to pass simple navigation arguments in a URL like this:

NavigationService.NavigateTo(new Uri("/Pages/QuestionPage.xaml?questionid=" + q.Id, UriKind.Relative));

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

Alternatively, you could try to implement your own NavigationService which supports passing parameters, but this is more complicated.

这篇关于ViewModel在MVVM Light中未收到消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-13 12:50