简体   繁体   中英

WPF MVVM - instantiating a ViewModel from another ViewModel

I'm new to MVVM and still learning. I used the article in the link below as an example to implement a simple app with a tabbed workspace that uses two views: "All Customers" and "New Customer".

https://docs.microsoft.com/en-us/archive/msdn-magazine/2009/february/patterns-wpf-apps-with-the-model-view-viewmodel-design-pattern#relaying-command-logic

In the example used by the article above, the shell app (MainWindowViewModel) uses a control panel with two buttons: "View all customers" and "Create New Customer". When the user clicks on these buttons, the respective view is open in the tabbed-workspace of the main shell.

My question now is: if we want to add a button "Create New Customer" on the "All Customers" view and when the user clicks on this button, the "New Customer" view opens as a tabbed workspace in the main shell, what would be the best way of doing this?

Do I need to use a messaging service to broadcast/send to all colleagues a "CreateNewCustomer" message, for example, and have the main shell (MainWindowViewModel) register to "CreateNewCustomer" and then its action would be to instantiate the "New Customer" view in its tabbed workspace?

Or is there a better/simpler/more elegant way of doing this? Please note that I am not using Prism, MVVMLight or any other MVVM framework. I am building my own framework as part of my learning.

Many thanks for taking your time to answer my question(s).

If I follow your description.

You should have a WindowViewmodel.

That maybe has a collection of viewmodels for your tabs. Or if it doesn't, it could do.

WHichever way things work, the usercontrol you are working on will have a button on it and it's a child of the same window you're going to show something else on.

Add a NewUserCommand to WindowViewmodel. This news up and adds NewCustomerViewModel to the collection your tabcontrol is bound to. That templates the tab into a NewCustomerView using viewmodel first.

The remaining problem is how you get from a button which is in a child usercontrol to the window's viewmodel. You do that by using a relativesource binding. Which will look something like:

{Binding DataContext.NewUserCommand,
  RelativeSource={RelativeSource AncestorType={x:Type YourWindowType}}}

This assumes you're ok with a tabcontrol for your "tabbed workspace". If you have windows in mind somehow then I recommend reconsidering that.

I would also say that learning wpf is hard enough without picking a framework to make your commands easier. I suggest you take a look at the source code for mvvmlight and relaycommand. There's a lot to it. Messenger is also quite a handy thing to use. I often don't use anything but relaycommand and messenger out mvvmlight btw.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM