Here is WPF application consisting from 3 UserControls:

enter image description here

UserControl3 is a part of UserControl2 content. I keep MVVM during developing and using Prism.

I need to invoke custom class method (which is model in terms of MVVM) in UserControl3 from view-model of UserControl1. The restriction that service in UserControl3 can't be singleton. I suppose to do it one of the following way:

  1. Using event aggregator from Prism. UserControl1 view-model is publisher and UserControl3 model is subscriber. For this I'll need to create unique Id in Window and pass it to UserControl1 and UserControl3.

  2. Creating service instance in Window and pass it to UserControl1 and UserControl3. Then UserControl1 just invoke method on this instance.

  3. Window pass UserControl2 instance to UserControl1. View-model in UserControl1 will just invoke method of UserControl2, which will invoke method of UserControl3 and so on.

It seems like 2 and 3 approaches violates MVVM. What will you prefer?

  • The smaller and the more general is the question the higher is the chance of it being answered here. – Den Sep 1 '16 at 12:38
  • @Den Thanks for your note, I reduced question. I can also remove list, but as well I know, questions without "what I tried" section are not welcomed... – Sam Sep 1 '16 at 13:55
  • It's generally hard to get a WPF answer here these days, SO is a better bet, even if it's about design. This question could theoretically be technology-agnostic by the way. I personally cannot see the screenshot, because my employer's IT is paranoid and blocked most of external image hosting. In my last WPF project I relied on ReactiveUI heavily to make state propagation easier. That and viewmodel composition. No mediators/event aggregators. – Den Sep 1 '16 at 14:36
  • I need to invoke custom class method (which is model in terms of MVVM) in UserControl3 from view-model of UserControl1 -- Why? – Robert Harvey Sep 1 '16 at 16:45
  • Microsoft seems to endorse using the Observer Pattern in MVC implementations, so I infer that this would extend to this scenario as well. – stephen.vakil Sep 1 '16 at 16:48

This question, while focusing mostly on WPF applications applies equally to any GUI application.

When you have two different pieces of the user interface that must interact, you are really left with two possible solutions:

  1. Events, which you outline as solution #1. The advantage here is the publisher and subscriber are decoupled, and do not have to know the structure of the user interface in order to do their job. The disadvantage here is that subscriber and publisher are decoupled, making UI problems harder to debug.

  2. Composition (in Object-Oriented terms). You need to encapsulate the logic somehow. If this logic is purely UI logic, then one User Control could have a direct reference to another, if and only if the structure of the UI will now and forever more facilitate this object relationship.

    If the two User Controls cannot know the structure of their containing window, go with option #1 above.

    If the logic is not UI logic, then a service class injected into each User Control upon object creation will work (also known as Dependency Injection).

My preference is to use events or messages between two UI components. An event can be generated by the user, or by the application.

  • Thanks for answer, but what I was talking about is how to not involve UI to processing data between model and view-model of different controls. This is why I don't want to pass Id through code-behind. But considering my question in terms of any GUI application, I agree that events is better solution, I'll just wait for a while to see if other opinions exist. My particular problem with Id I described in stackoverflow question. – Sam Sep 2 '16 at 9:54

I use MVVMLight, and I would send a notification message which my control would receive and then fire off service record. Same as firing an event in prism.

  • Thanks for your answer, I checked Greg Burghardt answer as more detailed. – Sam Sep 8 '16 at 11:19

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.