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

发布于 2024-12-05 13:45:53 字数 1045 浏览 1 评论 0原文

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



编辑

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

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

这是我将MVVM light导入项目后解决的方法。
在 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
}

它似乎自动工作..

Ps 感谢回复。我还将研究 Prism 的工作原理,看看使用它代替 MVVM light 是否有任何优势(但现在还不行)。

I got a wpf desktop application with 3 ViewModels.
I have 1 ViewModel that contains a tabhost and tabs. And I got 2 tabs. Each of those tabs has it's own ViewModel.
The problem I have is that in tab1 I have a listview with searchresults and a button. When I select one item in that list and press the button, I want to change tab and display information about that item I selected in tab2.
I have searched for a solution, but it seems to include creating all ViewModels in the MainViewModel and providing a reference of the MainViewModel to all the subViewModels.
Is there no other way?



EDIT

I just managed to solve my problems with MVVM light that I added to the project.

By binding a method in the MainViewModel and a property in it to the .xaml I can now call it from tab1 with info to tell it to change tab.
Also, by binding a method in tab2 I can now send over an item from tab1 in the same manner.

This is how I solved it after importing MVVM light into the project.
In tab1

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

In Main/tab2

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

It seems to automagically just work..

P.s. Thanx for reply. I shall look into how Prism work as well, and see if there is any advantages to use that instead of MVVM light(Not right now however).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

森罗 2024-12-12 13:45:53

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

该服务允许您从应用程序中的任何位置侦听和发布特定类型的事件,而无需将视图模型相互绑定。对于 MVVM 和其他松耦合设计来说,这是一个非常好的解决方案。它很简单,而且很有魅力。

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


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

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 的方法:)

您还可以看看这个相关问题:MVVM Light 中的 Messenger 类

A good solution to your problem would be to use the EventAggregator of Prism.

This service lets you listen to and publish a particular type of event from anywhere in your application without tying your view-models to each other. This is a really nice solution for MVVM and other losely-coupled designs. It is easy and works like a charm.

You can find the documentation here : EventAggregator
More information about Prism here : Prism on Codeplex


Here is a concrete sample. Imagine you want to change the title of the main Window from anywhere in the application. You would create this event:

public class TitleChangedEvent : CompositePresentationEvent<string>{}

Then you would suscribe to this event in your MainWindowViewModel like this:

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

And finally you can update the title from anywhere in your application like this:

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

Quite easy as you can see.


Smililarly with MVVM Light you would first create a message for notification:

public class TitleChangedMessage : GenericMessage<string>{}

Then you would listen to the message like this in your MainWindowViewModel:

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

And you would send an update like this:

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

This is the MVVM Light way to do it :)

You can also have a look at this related question: Messenger class in MVVM Light

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文