other View(s) dependency? - wpf

I have view like the image and ViewModel have commands to handle the button (1,2,3,4) clicks. In work area allow the user to give inputs. Depending upon the input users are allowed click the button;
Each Button leads one new Window(View with ViewModel; whose model will be taken from the inputs). The new window have its own logic to showing the data depending upon the model injected to the ViewModel.
As per the MVVM standards, where do I specify the respective View and ViewModels for the each Button? (In View / View model).
How can I specify the same?

Basically ViewModel is a link between View and Model, so each combination of View and Model should have a separate ViewModel (if valid).
In my experience in most cases we are dealing with two kinds of Views:
small views such as icons, advanced buttons and so on (which are more isolated and more likely to have no reference to their parents so they are easy to manage and to be generalized)
large views such as windows, panels (which have a lot of children and are more likely to be changed later)
For small views common ViewModels can be used for multiple Views. but as for large Views (considering possible changes in the future) it's better not to use a single shared ViewModel. however it's helpful to use a base ViewModel class to implement some shared functionality (if any).
So keeping that in mind and focusing to stay standard, I suggest:
ViewModels for secondary windows: (according to the question I think you need 4) Each have their independent functionality (you can derive them all from a BaseWindowVm).best practice here would be not to let them know about their parent (MainWindowVm) and just to set their event handlers when they are instantiated. This way you can avoid code coupling.
MainWindowVm: consists of 4 commands and some other inputs. Each command does these steps:
instantiates a View
instantiates a ViewModel for secondary window based on input
set Vm's event handlers
assign the Vm to DataContext of the View
add the Vm to some list in MainWindowVm (If you want to keep track of these windows)
ShowDialog()
The most important part is that since ViewModels communicate with each other, linking Views with each other only make it more complicated and more difficult to manage. so Views are like islands with bindings to their ViewModels and everything else is up to ViewModels.

Related

Should I dependency inject? How do I do it?

Okay, so I am working with Microsoft Prism in WPF using a MVVMC(or MVCVM) pattern.
In my ChatModule I have a series of Views, ViewModels, and one Controller.
For the Views I have
ChatAreaView - Displays the chat messages that come in to be read. This is hosted inside of a TabControl region so that I can have chat windows between the user and other users, or maybe file transfer windows, etc.
UserAreaView - This is a list of the users. Right clicking has context menu to interact with them... like sending a file or whispering.
MessageAreaView - This is where the user types in messages to be sent to all of the others.
For each view, I have a corresponding ViewModel. ChatAreaViewModel, UserAreaViewModel and MessageAreaViewModel. These ViewModels essentially only contain properties.
For example, the UserAreaViewModel defines a struct of type User which is essentially just a Name. Actually this is defined outside of the class, but still... it uses it. It has an ObservableCollection to store a list of all the Users who are currently connected. It also has ICommand properties defined to interact with the user. Right now I have SendFile, Whisper and Nudge... with intent on adding more in the future.
The Controller creates these views and ViewModels, and marriages them. It news them up, assigns the ViewModel as the corresponding View's DataContext, and sets all the initial properties of the ViewModel. Over the lifetime of the module, it will react to user interaction and execute DelegateCommands that it has assigned to each of the ViewModel's ICommand properties. These will further alter the state of the properties in a ViewModel.
I am using the actual types of Views and ViewModels, instead of interfaces, like such.
#region Views
ChatAreaView viewChatArea;
UserListView viewUserArea;
MessageView viewMessageArea;
LoginPromptView viewLoginPrompt;
#endregion
#region ViewModels
ChatAreaViewModel viewModelChatArea;
UserAreaViewModel viewModelUserArea;
MessageAreaViewModel viewModelMessageArea;
LoginPromptViewModel viewModelLoginPrompt;
#endregion
Would things be a lot more neat, less coupled if I defined interfaces for the Views and ViewModels, and operated on these interfaces within the controller instead of the concrete implementations? Could I then just register them with my Container in the Module class(which is essentially the root of each Module)?
What do I have to gain from doing this? How would I implement an interface for each view to distinguish them from the others? They don't really do ANYTHING except have XAML... and teh ViewModel's don't really do anything either except have certain properties. And those properties might be subject to change. On the UserAreaViewModel for instance, I will definitely want to add more commands so a user can interact with another user in different ways.
Can somebody help me out here? In my mind I'm thinking I should be abstracting this stuff, but I don't really know a logical way I should be going about it, or even if it's a wise idea to do so. What do I have to gain?
Thank you for your time. The below image is an example of what I'm working on. Ignore the Add new Item button and the styling of everything... that's not what I'm working on right now.
loosely coupled - can replace an entire class with altogether different implementation in future.
independent development.. can inject a dummy UI / view until final UI gets ready. two pieces can evolve at the same time (after having a common contract).
no need to add references to the modules (implementing the view). can use ConfigurationModuleCatalog to discover types from config file.

MVVM, should I put logic in model or view-model (controller)

I am new to MVVM and now doing some MVVM refactorying work on a silverlight project, suppose it is a book shopping application.
The View is a book list, I bind the title of the books to the ViewModel. So I have a public string Title { get; set; } in ViewModel, also a public string Title { get; set; } in Model (am I right?)
Now I want put a event handler to update the book title, should I put the event handler in ViewModel or Model? and what is the Model used for?
In my opinion "Neither"... Add controller classes to the mix of MVVM instead.
The problem with putting controller code in view models is that is makes them harder to test independantly. In many ways I see this as just as bad as code behind.
It seems to me that everyone assumes MVVM has no controllers as they left out the C. MVVM is really a variation of MVC "that just adds ViewModels".
Maybe it should have been called MVCVM instead?
ViewModels are only there to offload the "GUI" code from the view and to contain any data for binding. ViewModels should not do any processing. A good test is that your ViewModel is testable via automated unit tests and has no dependencies on data sources etc. They should have no idea where the data is actually coming from (or who is displaying it).
Although it can be overlooked/avoided, a Controller should be responsible for deciding what data model to display and in which views. The ViewModel is a bridge between Models (the M in MVVM) and Views. This allows simpler "separated" XAML authoring.
The pattern we are using successfully on all recent projects is to register controllers only, in modules, and initialise them at startup. The controllers are very light/slim and the only thing that needs to hang around for the life of the app listening for, or sending, messages. In their initialise methods they then register anything they need to own (views and viewmodels etc). This lightweight logic-only-in-memory pattern makes for slimmer apps too (e.g. better for WP7).
The basic rules we follow are:
Controllers make decisions based on events
Controllers fetch data and place it in appropriate View Model properties
Controllers set ICommand properties of View Models to intercept
events
Controllers make views appear (if not implied elsewhere)
View Models are "dumb". They hold data for binding and nothing else
Views know they display a certain shape of data, but have no idea
where it comes from
The last two points are the ones you should never break or separation of concerns goes out the window.
In simplest terms, the Model is the 'real' underlying data model - containing all the info for the booklist that might be needed by the application, able to get and set data from your database.
The ViewModel is an object that exists primarily to provide data binding for your View. It might be a subset of the Model, or it might combine properties from multiple Models into a single object. It should contain the necessary and sufficient properties to allow the View to do its job.
If the event handler relates to the View, then it belongs in the ViewModel. You might try using the Command Pattern (see Custom WPF command pattern example) if it fits your purpose.

Are current MVVM view model practices a violation of the Single Responsibility Principle?

With current practices (at least with WPF and Silverlight) we see views bound via command bindings in the view model or we at least see view events handled in view models. This appears to be a violation of SRP because the view model doesn't just model the view state, but responds to the view (user). Others have asked how to build view models without violating SRP or asked whether their implementations do so (this last is the controller in MVC, but roughly analogous).
So are current practices a violation of SRP? Or is "view model" really a collection of things that don't violate SRP? To frame this a bit, it seems we need to know what is the single responsibility or if there are multiple responsibilities in the concept, are the individual responsibilities split out, conforming to SRP. I'm not sure.
Wikipedia's definition of view model says
[T]he ViewModel is a “Model of the View” meaning it is an abstraction of the View that also serves in data binding between the View and the Model
This seems good enough for SRP, but then the entry later says (my emphasis added)
[The ViewModel] acts as a data binder/converter that changes Model information into View information and passes commands from the View into the Model
In a Prism blog post about the view model's role, the author says (again, my emphasis)
What it boils down is that the view model is a composite of the following:
an abstraction of the view
commands
value converters
view state
I'm sure I've missed many definitions out there, but they seem to fall into these categories:
Single "vague" responsibility of modeling view state (so what do we
mean by state)
Multiple responsibilities (view state, user interaction (i.e.
commands))
A composite of single specific responsibilities (abstraction,
state, interaction, conversion), thus having a single
responsibility: "managing all that stuff".
If you're curious, I "care" about this because (2) feels right, but seems counter to the prevailing implementations.
Single Responsibility as Martin defines it:
"THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE."
A ViewModel, as far as MVVM is concerned is really just a specialized implementation of a Presentation Model.
So while it could be argued that a Presentation Model should only represent the state of the UI, and that a Presenter/Controller should always broker the commands between the UI and the Presentation Model. If one follows this idea, with SRP dividing on State and Commands, then adding a command should not affect the class that represents state. Therefore MVVM would break SRP.
However...
I think this is grasping at straws. MVVM is a fairly specialized implementation used basically in WPF/Silverlight (and now browser clients).
Patterns are designed to make designs simpler where the alternative would be more cumbersome or less maintainable. Since MVVM is designed to take advantage of the extremely rich data binding capabilities of the presentation technologies, then it is a worthwhile trade off.
No! MVVM does not violate SRP, (the programmer does, lol!)
There is no reason that using the MVVM pattern needs to ignore the SRP. MVVM does not mean that there is only one Model Class, one View-Model Class, and one View Class. Certainly, if you only had one View Class, you could only ever show one simple screen.
Those classes that are in the View tier, should be responsible for one thing; doing, deciding, or containing. A View can consist of several sub-views who's jobs are to do certain pieces of the users interractions. Consider a basic form, it has a display grid, items in the grid can be edited, and there is a "Save" button.
The main View would be a container for two other views; the datagrid (a user control, or something) and a command control. The datagrid then is responsible for choosing the right childview to render data in; in essense it's a container that databinds. The View to edit items is a child view of the datagrid, which is in-turn a child of the main View. Lastly the command control is a set of buttons (in this case a single one) who's single responsibility is to raise signals that commands have been issued by the user.
In this way the Edit View (used by the DataGrid) is agnostic about what uses it, and has one responsibility; Same with the command control. Likewise the DataGrid doesn't care about who uses it, only that it can contain the Edit View (child). Nice SRP there.
ViewModels to match the Views (and children) are also responsible for one thing. The Edit View Model is a container to which the Edit View Binds; it simply contains the data fields that can be displayed/edited. It doesn't care about anything but signalling when one of its properties change. The Command Button View Model is a class that does things. It's commands are bound to the buttons, and it will do work based on what the user clicks on. It will have to have access to other parts of the ViewModel(s) to do it's work.
The main page View Model is there to contain the other child views. It's sole responsibility is as an initializer, making all the required ViewModel instances, and passing constructor parameters to other ViewModel instances (say, the Command Button View Model so it knows where to get data for it's work)
It's natural to cram a whole bunch of functionality into a single ViewModel that a large View would bind to. But it doesn't have to be that way, and SRP can be maintained in MVVM.
The main goal of MVVM is to allow for testable design, the Model layer can be tested independantly, all classes in the Model can easily follow SRP. The ViewModel can be tested without the need of a view; it gets trickier to think SRP in the ViewModel, but it is certainly doable; just remember to break out your classes so they only have one concern. The View is bound to parter ViewModels, with any luck, your testing of the ViewModel makes snapping the View(s) on super easy. Remember you can have each View-let adhere to SRP to be part of a larger conglomerate View (container).
TL;DR?
To answer your question directly, the View is a collection of classes that does not break the SRP. Thus, when the ViewModel is abstracted from the View(s) (View-First), they are also a collection of classes that adhere to good SRP.
I consider many of the current practices around MVVM violate SPR (at least). This is yet another situation where simply adding controllers back to MVVM would solve all the problems cleanly. I call it MVCVM :)
The pattern we are using successfully on all recent projects is to register controllers only, in modules, and initialise them at startup. The controllers are very light/slim and the only thing that needs to hang around for the life of the app listening for, or sending, messages. In their initialise methods they then register anything they need to own (views and viewmodels etc). This lightweight logic-only-in-memory pattern makes for slimmer apps too (e.g. better for WP7).
The problem with just using VMs, as you have found, is that eventually you hit cases where they need to know about views, or commands, or other stuff no self-respecting ViewModel should be involved with!
The basic rules we follow are:
Controllers make decisions based on events
Controllers fetch data and place it in appropriate View Model properties
Controllers set ICommand properties of View Models to intercept events
Controllers make views appear (if not implied elsewhere)
View Models are "dumb". The hold data for binding and nothing else
Views know they display a certain shape of data, but have no idea where it comes from
The last two points are the ones you should never break or separation of concerns goes out the window.
Simply adding controllers back into the MVVM mix seems to solve all the problems we have found. MVVM is a good thing, but why did they not include controllers? (but this is of course just my opinion) :)
What it boils down is that the view model is a composite of the following:
an abstraction of the view
commands
value converters
view state
I don't see why you've separated the first two items. Commands are part of the view.
As for the rest - you're right. In some cases. I've built applications where the tasks of value conversion and maintaining view state were sufficiently complex that it didn't make sense for a single view model class to do it all, and I broke them out into separate classes that interoperate with the VMs.
So?

MVP and UserControls and invocation

I'm having some fun trying to get my head around some MVP stuf, as it pertains to User Controls. I'm using .NET WinForms (or something close to it) and Supervising Controller pattern (well, I think I am :).
The User Control is itself part of an MVP application (its the View and has an associated Presenter etc). The Presenter is always started first, and it starts the Model(s) and then View(s). The View builds its UI, part of which will be to NEW the UC, which is the View.
Now the (form) Presenter needs to know about the UC Presenter, but I'm thinking that it doesn't know anything about how the View is composed. The form Presenter doesn't, for instance, know that the UC is part of the form's Controls collection, nor should it.
Furthermore, the design experience should not be changed; IOW the dev of the View (form) should just be able to select a User Control from the toolbox and drop it on a form.
So, on to my questions. Firstly, are my assumptions above correct? Somewhat misguided? Messed up? WTF are you thinking?
Secondly, is it right (enough?) to have the form View invoke the UC View, and the form Presenter invoke the UC Presenter and have some mechanism to tell the UC View what its Presenter is? This breaks my "Presenter first" rule, but I'm not sure how else to do it.
Any other thoughts, suggestions, comments gladly accepted.
-- nwahmaet
A presenter should be thought of as "autonomous state" in the presentation tier. This means that it is responsible for ensuring that the view's presentation of the model's state is in sync. The reason I bring this up is because the "pattern" of MVP often gets lost in the dogmatic view of how things should be separated. It seems that this is one reason Martin Fowler decided to try to clarify the terminology around the MVP pattern.
My favored flavor of MVP is the passive view, so my answer is based off of that.
I implement composite user controls and forms very often using the passive view pattern. There are essentially 3 different configurations:
One presenter for all user controls in the hierarchy. Flatten the view using an interface.
One presenter for each user control in the composite tree. Each parent presenter is responsible for instantiating and initializing its child presenters. The user controls are created at design time, and are able to function without a presenter (with no presentation behavior)
One presenter for each user control in the composite tree. All of the presenters are loosely coupled through a higher level controller class. The controller class is responsible for construcing the presenter, wiring them up, and coordinating their events.
Although it is a solution of last resort for me (because of its complexity), I think that the last option is the solution that you are looking for.
I've been running up against this exact problem for several months in an application I'm working on. The conclusion that I've very recently come to is that in many cases it might be impossible to apply the MVP pattern at both the window AND user control levels, without "breaking" the pattern.
My thought on it is that the user control is part of the view implementation, and the presenter should not know what is going on inside the view implementation, which means that the window-level presenter by extension should not know about the user control's presenter, and hence there should be no communication between them, including instantiation of the latter by the former. It might be argued that the user control's presenter is part of the window view implementation, and so the window view may instantiate the user control presenter. But it cannot inject the model classes that the presenter needs, because the view isn't supposed to be aware of them.
The conclusion that I think I am arriving at is that ALL user controls are view-implementation-specific, and so should be contained completely within the view silo of the larger pattern. As such, they don't get to have their own presenters... At least not bundled up with the control implementation itself. Instead they should be manipulated indirectly by the parent window's presenter, via pass-through fields exposed on the view interface. In short, the user control is exposed to the presenter not by its own interface, but rather via a common pass-through interface implemented by its parent view. Call this a "partial view interface".
Your presenter can then contain instances of a re-usable sub-presenter class which works only with this partial view interface, and the relevant pieces of the model. This will allow you to avoid re-writing the presenter code to translate from the model every time you need to use the control, AND it prevents the window view from needing to know about the model in order to pass info through to the control's presenter.
What this effectively does is it further separates the user control, as a module, from your data model. This makes sense if you think of a user control, as a whole, as an element of the view implementation. As a re-usable unit, it is a piece of view functionality, and no part of it should be tied to your data model.
Your questions is general that a variety of schemes could apply.
In this case my guess is that you should look at Observer Pattern.
You have a interface that anything that uses that view would implement. Then it would register itself when the application initializes with a collection of those interfaces. Any command that needs to update that view would traverse the collection notifying that each view should be updated.
Unlike typical examples the views would be User Controls. You have the flexibility of making any UI element implement that interface so you could use dialogs, full forms, etc in addition to your User Control.
Finally remember the User Control is NOT the view but the implementation of the View. Whatever scheme you adopt you can define what the View as deep as you want and have the User Control implement that interface.

How to build the ViewModel in MVVM not to violate the Single Responsibility Principle?

Robert Martin says: "There should never be more than one reason for a class to change".
Let's consider the ViewModel class which is bound to a View. It is possible (or even probable) that the ViewModel consists of properties that are not really related to each other. For small views the ViewModel may be quite coherent, but while the application gets more complex the ViewModel will expose data that will be subject to change for different and unrelated reasons.
Should we worry about the SRP principle in the case of ViewModel class or not?
The ViewModel single responsibility is to provide the View the information it needs. If the View needs different and unrelated properties that is not important as the ViewModel only has one reason to change and that is the View showing different properties. So you shouldn't worry too much.
That said, if the ViewModel does get huge, maybe you could think about dividing the view into several subviews to improve reusability and keep the Views and the ViewModels manageable.
I agree with gcores.
Once you see ViewModel grow to more than two screenfuls of text, it is time to consider splitting ViewModel into several child models.
Another rule of thumb is that I never have more than two levels of nesting inside XAML file -- if one part of the view becomes too complex, it is time for view refactoring -- extract inner XAML into separate UserControl and create corresponding ViewModel, which will be default data context on child view.
Yes, but that doesn't mean poor design couldn't force you into it.
I agree that splitting your screens into multiple Views with multiple ViewModels is necessary to reduce bloat and complexity. Here's another pattern I've employed to help stick to SRP using MVVM:
Here's one scenario. My ViewModel needs to obtain data and respond to filter commands from the UI. I create the ViewModel to be composite in structure. That is, child classes that have access to private members of the ViewModel perform linear tasks such as handling the filtering. I might also have another child class that performs the necessary logic for selection of items based on criteria. You get the idea. Once the ViewModel is performing certain functions that span across several methods, it may be a good candidate to delegate to a child class. The child classes remain part of the main ViewModel, so it's just a way of reducing the size of the ViewModel and makes unit testing these linear operations easier.

Resources