Silverlight 4.0 如何使消息目标成为目标消息的唯一接收者?

Silverlight 4.0 如何使消息目标成为目标消息的唯一接收者?,silverlight-4.0,wcf-ria-services,mvvm-light,Silverlight 4.0,Wcf Ria Services,Mvvm Light,第一次海报 我将MVVM Light与Silverlight 4和RIA服务一起使用。这是一次学习经历!但到目前为止,它工作得很好。我想知道两件事。现在,我正在使用Messenger框架将EntityObjects传递回ViewModel。例如,我需要打开具有特定“课程”对象的视图模型。因此,我实例化了该视图,该视图通过课程向ViewModel发送一条消息。我有几个问题 第一个问题:这是最好的方法吗?我不想使用棱镜、统一或其他任何东西,因为我没有时间学习它们。(对我来说,这是MVVM Light

第一次海报

我将MVVM Light与Silverlight 4和RIA服务一起使用。这是一次学习经历!但到目前为止,它工作得很好。我想知道两件事。现在,我正在使用Messenger框架将EntityObjects传递回ViewModel。例如,我需要打开具有特定“课程”对象的视图模型。因此,我实例化了该视图,该视图通过课程向ViewModel发送一条消息。我有几个问题

第一个问题:这是最好的方法吗?我不想使用棱镜、统一或其他任何东西,因为我没有时间学习它们。(对我来说,这是MVVM Light的一大亮点。Light部分。)但我看不到任何其他方法可以将参数传递给VM定位器

第二部分是,这意味着我正在将消息从视图发送到该视图的特定ViewModel。我的消息如下所示:

  Tuple<Models.Course, Services.VWDS> courseDomainContextTuple = new Tuple<Models.Course, Services.VWDS>(Course, DomainContext);

  NotificationMessage<Tuple<Models.Course, Services.VWDS>> message = new NotificationMessage<Tuple<Models.Course, Services.VWDS>>(this, this.DataContext, courseDomainContextTuple, Models.MessageString.EditCourse);

  Messenger.Default.Send<NotificationMessage<Tuple<Models.Course, Services.VWDS>>>(message);  
Tuple courseDomainContextTuple=新元组(课程,域上下文);
NotificationMessage=new NotificationMessage(this,this.DataContext,CoursedMainContextTuple,Models.MessageString.EditCourse);
Messenger.Default.Send(消息);
如你所见,我正在捆绑课程和DomainContext(啊,RIA,为什么不让我从EntityObject获取上下文?)并将它们发送到ViewModel(即“this.DataContext”)——是的,我知道我应该为该消息创建一个类

问题是——每个获得课程和DomainContext的对象都会收到该消息,而不仅仅是我指定的目标VM

所以,第二个问题:这是出于设计,还是一个bug,还是我做错了什么


谢谢

当您需要从一个ViewModel到另一个ViewModel进行通信,或者需要发送一条消息,其中零到多的东西可以对其进行操作时,消息传递更为有用。根据视图的代码,我认为您应该直接调用ViewModel。这很简单——下面是我在代码中通常的做法

public partial class ExampleView : UserControl
{
    private IExampleViewModel ViewModel
    {
        get { return this.DataContext as IExampleViewModel; }
    }

    public ExampleView()
    {
        InitializeComponent();

        // Call directly to my View Model
        ViewModel.SomeMethod();

        // Register for View Model's event
        ViewModel.SomeEvent += ViewModel_SomeEvent;
    }

    private void ViewModel_SomeEvent(object sender, EventArgs e)
    {
        // do stuff
    }
}

在示例中,我还介绍了如何通过事件处理从ViewModel到View的通信。

要回答您的第二个问题,如果您发送的是特定类型的NotificationMessage,则注册相同消息类型的任何内容都将收到该消息。如果要限制接收消息的人,请创建一个从MessageBase或NotificationMessage继承的新消息类或其他类型,使用发送消息,或在消息接收处理程序中使用If语句来筛选不关心的消息。

好的,因此为ViewModel创建一个接口以防止耦合。我想这至少对设置实体对象是有用的,即使其他一切都不同。你不必使用接口,这只是一个好习惯。我承认它确实为ViewModel的创建增添了仪式,但我发现它值得付出额外的努力。另外,我做的另一件您不必做的事情是在ViewModelLocator中使用DI/IoC容器。我使用Ninject,但你也可以很容易地使用Unity或Castle Windsor。是的,我都懂。我的观点是,确实存在一条消息,它有一个目标,这似乎意味着目标应该是接收消息的人。由于这似乎很容易实现,我想知道它是否真的不存在,或者我是否没有设置目标或发送正确。好的,我没有注意到您在示例中为NotificationMessage设置了目标。尝试将this.DataContext转换为您的确切ViewModel类型,看看这是否会产生影响?如果没有,请尝试将MVVM Light Toolkit项目添加到您的解决方案中,并逐步查看其他ViewModel也收到此消息的原因。要么你会发现一个讨厌的bug,要么你会发现你的代码出了什么问题。:-)