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 tab1Messenger.Default.Send<string, tab2ViewModel>(--object to send to tab2--);
Messenger.Default.Send<int, MainViewModel>(--tab index--);
In Main/tab2
Messen开发者_JAVA百科ger.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).
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
精彩评论