3
votes

I'm working on a project in WPF-MVVM where I have a Main Window that contains a Tab Control with two tabs. Each of these tabs has a button on it.

In this project, there are 3 different View Models, one for the Main Window and one for each of the tabs. When one of the buttons is pressed, I would like the "parent" view model (the View Model for the Main Window) to perform some action, such as closing the application.

What is the proper way to go about having the View Model for the Tabs ask the Main View Model to perform this action?

Screenshot of Application

Code on Pastebin

Note: I am not using any sort of framework such as MVVM Light or Prism.

2
Have a look at Commands wpf-tutorial.com/commands/introduction - devmb
@komaflash Yeah, I'm familiar with binding to Commands in the view, I just hadn't thought of using them in the context of ViewModel -> ViewModel communication. Seems like it could work fairly well to take a Command (CloseCommand, etc) or whatever as a constructor argument and then just call that command whenever needed. - Everix
You coudl use relative binding, have a look at my answer. - devmb
Could you please mark my post as answer if it was helpfull? - devmb

2 Answers

2
votes

You could access the parents DataContext by using a relative binding like this:

Binding="{Binding RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type Window}}, Path=DataContext.AllowItemCommand}"
0
votes

I'm not sure about proper way but here are two options that come to mind and seems pretty proper to me :)

One is to add MainWindowViewModel Parent {get;set;} property to child model and then in main MainWindowViewModel to set that property whenever you add or remove child to a Tabs collection (as it's ObservableCollection, you can add event handlers to it to make sure, to set Parent property no matter how child is added to collection). Something like this is used in Win Forms to maintain parent/child relation between window and controls.

Second one is to add event to child ViewModel and to subscribe/unsubscribe to that event in parent ViewModel when child is added/removed (similarly to first option just with events, not with property). Then from event handler you can call method you wanted

First option is more direct answer to your question (calling parent's method from child). Second option is more general, child doesn't have to be aware of parent and you can subscribe to event from some other kind of parent or whatever you want.

Which is more proper depends on your need for current project.