从ViewModel更改选定的选项卡并在ViewModel之间发送对象

时间:2011-09-21 09:30:37

标签: c# wpf xaml mvvm

我有一个带有3个ViewModel的wpf桌面应用程序。 我有一个包含tabhost和标签的ViewModel。我有两个标签。每个选项卡都有自己的ViewModel 我遇到的问题是在tab1中我有一个带有searchresults和一个按钮的列表视图。当我在该列表中选择一个项目并按下按钮时,我想更改选项卡并显示有关我在tab2中选择的项目的信息。
我已经搜索了一个解决方案,但它似乎包括在MainViewModel中创建所有ViewModel并向所有subViewModel提供MainViewModel的引用。
没有别的办法吗?



修改

我刚刚设法解决了我添加到项目中的MVVM灯的问题。

通过将MainViewModel中的方法及其中的属性绑定到.xaml,我现在可以从tab1调用它,并使用info告诉它更改选项卡。 此外,通过绑定tab2中的方法,我现在可以以相同的方式从tab1发送一个项目。

这是我将MVVM灯导入项目后解决的问题。
在tab1

Messenger.Default.Send<string, tab2ViewModel>(--object to send to tab2--);
Messenger.Default.Send<int, MainViewModel>(--tab index--);

在Main / tab2

Messenger.Default.Register<int>(this, ChangeTab);
public void ChangeTab(int i)
{
   SelectedTabIndex = i; //Bound property in .xaml
}

似乎自动化工作..

P.S。谢谢回复。我将研究Prism如何工作,并看看使用它而不是MVVM光是否有任何优势(但现在不是)。

1 个答案:

答案 0 :(得分:1)

解决问题的一个好方法是使用Prism的EventAggregator。

此服务可让您从应用程序的任何位置收听和发布特定类型的事件,而无需将视图模型彼此关联。这对于MVVM和其他丢失耦合设计来说是一个非常好的解决方案。这很容易,就像一个魅力。

您可以在此处找到文档:EventAggregator 有关棱镜的更多信息,请访问:Prism on Codeplex


这是一个具体的样本。想象一下,您想要从应用程序的任何位置更改主窗口的标题。您将创建此事件:

public class TitleChangedEvent : CompositePresentationEvent<string>{}

然后你会在你的MainWindowViewModel中承认这个事件:

eventAggregator.GetEvent<TitleChangedEvent.Suscribe(
(newTitle) =>
{
    this.WindowTitle = newTitle;
});

最后,您可以在应用程序的任何位置更新标题,如下所示:

eventAggregator.GetEvent<TitleChangedEvent>().Publish("This is a new title!");

你可以看到很简单。


使用MVVM Light,您首先要创建一条通知消息:

public class TitleChangedMessage : GenericMessage<string>{}

然后你会在你的MainWindowViewModel中听到这样的消息:

Messenger.Register<TitleChangedMessage>(this, 
(message) =>
{
    this.WindowTitle = message.Content;
}

你会发送这样的更新:

Messenger.Send<TitleChangedMessage>(this, new TitleChangedMessage("This is a new title!"));

这是MVVM Light的方式:)

您还可以查看以下相关问题:Messenger class in MVVM Light