Here is WPF application consisting from 3 UserControl
s:
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:
-
Using event aggregator from Prism.
UserControl1
view-model is publisher andUserControl3
model is subscriber. For this I'll need to create unique Id inWindow
and pass it toUserControl1
andUserControl3
. -
Creating service instance in
Window
and pass it toUserControl1
andUserControl3
. ThenUserControl1
just invoke method on this instance. -
Window
passUserControl2
instance toUserControl1
. View-model inUserControl1
will just invoke method ofUserControl2
, which will invoke method ofUserControl3
and so on.
It seems like 2 and 3 approaches violates MVVM. What will you prefer?
Best Answer
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:
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.
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.