2010-09-21 48 views
1

第一次海报。如何使消息目标成为目标消息的唯一配方?

我正在使用Silverlight 4和RIA Services的MVVM-Light。这是一次学习体验!但到目前为止,它的工作美丽。我想知道两件事。现在,我使用Messenger框架将EntityObjects传递回ViewModel。例如,我需要使用特定的“课程”对象打开视图模型。所以我实例化视图,并且视图向课程发送一个消息给ViewModel。我有几个问题。

第一个问题:这是做这件事的最好方法吗?我不想使用Prism或Unity或其他任何东西,因为我没有时间去学习它们。 (对我来说,这是MVVM Light。Light部分的一大亮点)。但是我看不到任何其他方式将参数传递给VM Locator。

第二部分是,这意味着我从View发送消息到该View的特定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); 

所以,你可以看到,我捆绑场和DomainContext(RIA啊,为什么你会不会让我从EntityObject获取上下文?)和发送他们到ViewModel(这是“this.DataContext”) - 是的,我知道我应该为这个消息做一个类。

问题出在这里 - 每个获取课程和DomainContext的对象都会收到该消息,而不仅仅是指定了目标的虚拟机。

所以,第二个问题:是由设计,还是一个错误,或者我做错了什么?

谢谢!

回答

1

要回答第二个问题,如果您要发送特定类型的NotificationMessage,则注册该相同消息类型的任何内容都将收到该消息。如果要限制接收消息的人,可以创建一个从MessageBase或NotificationMessage继承的新消息类,或者使用Token发送消息,或者在消息接收处理程序中包含if语句以过滤掉不关心的消息关于。

+0

是的,我明白了。我的观点实际上是有一个消息,它有一个目标,这似乎暗示目标应该是接收消息的目标。由于这似乎很容易实现,我想知道它是否真的不存在,或者如果我没有正确设置目标或发送。 – BoB 2010-09-21 17:09:58

+0

好吧,我错过了你在你的例子中为你的NotificationMessage设置了一个目标。尝试铸造这个。DataContext作为您的确切ViewModel类型,看看是否有所作为?如果没有,请尝试将MVVM Light Toolkit项目添加到您的解决方案中,并逐步了解其他ViewModel为什么也收到该消息。要么你会发现一个令人讨厌的bug,否则你会发现你的代码有什么问题。 :-) – 2010-09-21 17:34:13

+0

这是另一个好主意,谢谢! – BoB 2010-09-21 22:53:56

1

如果您需要从一个ViewModel与另一个ViewModel进行通信,或者您需要发送一个消息,其中零到多个事件都可以对其执行操作,则消息传递将更加有用。从你View的代码背后,我认为你应该直接调用你的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-through事件的通信。

+0

好的,你可以为你的ViewModel制作一个界面来防止耦合。我想这对于至少设置实体对象将是有用的,即使其他一切都不同。 – BoB 2010-09-21 17:05:48

+0

你不必使用接口,它只是一个很好的习惯。我承认它确实为ViewModel的创建添加了仪式,但我发现它值得额外的努力。另外,我不需要做的另一件事是在ViewModelLocator中使用DI/IoC容器。我使用Ninject,但你也可以轻松使用Unity或Castle Windsor。 – 2010-09-21 17:30:15