Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm in the design phase of a WPF application with complex requirements:
I have to control the view by code because I have to enable, disable or hide elements depending on the user permission. Additionally in a TreeView I have to control the ContextMenu of the TreeViewItems depending of the Item-Type (internal logic) and the dependency of the user permission.
The Data to display are loade by stored procedures to datasets (multiple tables).
What's the experience with MVVM and maintenance (code complexity of MVVM compared with direct code behind) and all the stearing of controls visibility.
Automatic testing is not needed because the visible part must be included in the testing all the time (visibility of controls depending on loaded data)
Any sugestions are welcome
Being at the design phase makes this much easier to suggest patterns and practices, your question isn't very clear, so I'll address each point you have made.
I have to control the view by code because I have to enable, disable or hide elements depending on the user permission. Additionally in a TreeView I have to control the ContextMenu of the TreeViewItems depending of the Item-Type (internal logic) and the dependency of the user permission.
This sounds pretty straightforward, using the MVVM design pattern in this scenario would most probably require an IValueConverter to convert a view model Boolean property to a view-friendly Visibility value. This explains how you can achieve that.
The Data to display are loade by stored procedures to datasets (multiple tables).
I would suggest looking into the Repository Pattern. This, coupled with the MVVM design pattern should suit your requirements nicely.
What's the experience with MVVM and maintenance (code complexity of MVVM compared with direct code behind) and all the stearing of controls visibility.
The purpose of MVVM isn't to have no code-behind, it's to ensure that code belongs in the right place. Code-behind is not a bad thing, it's view related code. There is a much more detailed answer here.
In your scenario, it's more than likely that you need properties in your view model to indicate whether the user has the authorization to view certain controls, I assume these permissions are held in the database, therefore the properties would need to live in the view model as you can't get to the database from the view. I hope that made some sense.
MVVM is more maintainable than a code-behind solution as your view models are decoupled from the view, therefore if the view changes, the view model does not necessarily need to change too. This is also true for repositories and models.
MVVM paves the way for a more agile solution.
I came from a winforms world, and implementing any MVX style pattern seemed like more hassle but after working on WPF, I can say that MVVM is the best way to proceed. The whole mechanism is supported out-of-the-box.
First, the key benefit is that it enables true separation between the 'View' and 'Model'. This meane that if/when your model needs to change, it can without the view needing to and vice-versa.
Second, your 'model' might have all the data required by your 'view' but this data might be required by your 'view' in some other way. For these transformations 'view model' is required, whithout which these changes would be needed with duplication in model.
You can also use a 'viewmodel' to aggregate parts of your model that exist in separate classes/libraries to facilitate a more fluent interface for the 'view' to deal with. It's very unlikely that you'll want to work with data in your code in the same way that a user will want to or will want that data presented to them.
On top of that, you get support for automatic two-way databinding between the 'view' and 'viewmodel'.
I would also recommend the video here:
http://blog.lab49.com/archives/2650
The scenario you are describing is nearly a "perfect-fit" for using MVVM. You can control the visibillity depending on the permissions just by using bindings in the view. You will not need to write any code-behind in the view (beside you have to do some specific UI things) because the entire connection between your "data" (models) and the displaying (view) is done in the viewmodel.
That also enhances the maintainability, you can touch the view without changing the viewmodel and vice versa.
At the beginning it will be a bit overwhelming and you have to create many properties which seems a bit messy.
In a nutshell:
View: just the form (layout) the user will see (displaying the data)
ViewModel: the logic which (in a way) "controls" your view and connects it with your data (models)
Model: your business logic
For example: In the viewmodel you can set the state of a property which indicates if a control element is visible for the user or not and this property is then bound to the view. In the view you do nothing beside binding the property in the XAML code. It's a good way to stay clean.
I hope this was a bit helpful.
EDIT: here is a quickstart and here are some further information
Related
In learning Xamarin.Forms/UWP/WPF tutorials always tout MVVM as the design pattern of choice and I've followed suite, but I've never understood why. To contrast, in asp.net MVC the templated framework is used to great effect, Controllers deliver models to the view (HTML of some sort).
But in the Xamarin.Forms/UWP/WPF and others, we create a completely new class, ignore the code-behind file that cannot be removed and relegate it to telling our view where to look when binding data.
The only reason I could think of that makes MVVM better is if we could supply logic where different VM's could be 'injected' into the same view, maybe that would justify it.Though I have no idea how to do that.
Otherwise, how is creating a view model class better than using the code behind file? Is it really worse separation of concerns just because the view and code behind have the same name and are instantiated together?
MVVM pattern is much cleaner than using code-behind.
Separation of concerns
Imagine you have a view and a code-behind implemented. Now the business comes with a request to completely change the way the controls are presented - replacing them with new controls, changing layout and so on. Chances are, you will be forced to rewrite a lot of code just to satisfy the requirement, because the code-behind is directly tied to the view.
Now in case you have MVVM in place, you can easily swap the View part of the equation for any view which utilizes data binding to the right properties in a View model. You could easily present a single View model in several different ways - like creating multiple different views for different user roles while the view model stays exactly the same, you just choose what to display and how.
What view model actually creates is a middle layer between data and their presentation and makes it possible to more easily transform the data the view uses and change the presentation without affecting the view model if the interface is kept intact.
Data binding
Also if you are meaning purely code-behind without data-binding, the advantages of MVVM become even clearer. When you have a data-bound property that updates after user input in a TwoWay manner, for example if you have a form the user has to fill out, you don't have to remember to fetch the latest "changes" from the control using Text property, you know the latest version is already there in the data-bound property. In addition, you can add validation in the property setter, you can update other properties in the setter as well to orchestrate data handling in a much more abstract way than with code-behind approach, where you are tied to events and having to remember where the data come from and which specific controls and which specific properties you have to update. Imagine you display a given text in multiple places - with data binding you just set a single property and rely on {Binding} to display the text in all bound controls. With code-behind only, you need to remember which concrete controls display the text and when you add a new control, you have to update the code-behind appropriately, which is far less convenient.
Cross platform development
Another example would be having to develop a cross-platform application with native UI using MvvmCross. Here you can decide that some views or some functionality will not be available for certain OS or that you want to just implement it later. This is entirely possible - you just don't provide the UI for that functionality and the view model can stay the same.
View state
Finally - having all view state in code-behind means that when you navigate away, you must store the state somehow and restore it when navigating back because a new page is created. With MVVM you may decide to keep the view models of the navigation stack in memory and when navigating back just set the DataContext of the page to the existing view model instance to get back just in the same state as you left off.
Overall I see MVVM as a great pattern to improve flexibility of your codebase and it makes your solution more future-proof and resilient to changes.
I know that in MVVM, we want to propagate user input from the view to the view model via data binding, and give the reflected view state in the view model to the model, where we write the business logic code, and update the user with the result via events.
However, does it mean that every change in the view must be done outside of the xaml.cs file?
Take for example a WPF application for sliding puzzle:
If we want to write an algorithm to solve the puzzle, we'll put the code in the model.
However, assume we want to update the grid after the user clicked the down key.
Checking if such move is possible, redrawing the board or giving the player any feedback (if the move is legit or no) should be done in the view? (the xaml.cs file)
More generally, are there "rules of thumb" to decide what to handle where?
Quick recap for the MVVM layers (or "rules of thumb"):
Model: Contains only the data used by the view models. As an exemple, consider business objects coming from database as "models".
View: Connection between the user and the view model. You can use multiple views for a same view model. If the view model changes and updates, the view should show the changes.
ViewModel: Contains the "business logic" between the view and the model. As such, commands, possible actions and algorithms are stored here. The view model dictates what is possible and what is not.
The communication between layers needs (that's the part necessary for MVVM) to be interchangeable, meaning the view model can be used with differents compatibles views and the model can be used by differents compatibles view models. To cut down on the dependencies of the multiples layers: the layers should not communicate directly between them. We use commands, events and direct bindings.
However, does it mean that every change in the view must be done outside of the xaml.cs file? [...] However, assume we want to update the grid after the user clicked the down key. Checking if such move is possible, redrawing the board or giving the player any feedback (if the move is legit or no) should be done in the view? (the xaml.cs file)
No. The view model should explicitly tell the view what is possible and what is not. The view shows that the action is possible or not: it does not decide if it is possible. Such decision is in the business logic, so in the view model.
As a trail of thoughts, take what it is said about interchangeable views. If you switch out the view foo for another view bar to show your puzzle and you did put the decision about "what's possible" in the view, you will have to rewrite the decision tree/algorithm in the new view bar and thus, duplication of code/logic.
When the decision is higher up, the view reflects what the view model is telling him. If the view model wants the view to "refresh" or to tell the user "hey, that's an illegal move", the view model will do so via commands and events. After receiving such events, the view could then decide what to do with it:
Show an error message about the illegal move
Show a tooltip that the move is illegal
Flash and shake the window with a beep to show that the move is illegal
Many more implementations...
I do hope I answered your question as thoroughly as possible.
My 10 cents:
If my experience have taught me anything, it's that it's almost impossible to fit all problems with the same, general solution.
In the case of MVVM, some things I've learned (the hard way):
It's easy for the view model to devolve into God classes (ie, mix of purely view-related logic + some business logic + etc..)
Depending on the application tiers, some times it makes sense for logic to work on view models; other times, it's better for logic to work on the models instead.
Whatever layers I/you/anyone think certain classes/logic should go, will most likely have to change as development progresses.
Instead, my approach is usually:
Prepare
Model (for serialization, very little logic),
View Model (with property change bindings for view) and
View (thin layer, binds almost directly to View Model)
Write the majority of the application logic in the View Model.
Easier to have logic in here, so view bindings can work
This is the stage where the View Model layer bloats up
When the application is finally working, begin refactoring
For rich-client applications, I find my Model classes to be almost purely data
The View Model will most likely be refactored into 2 layers: MVM (Model-View-Model) and VVM (View-View Model)
MVM: This is where common, business-related logic/objects sit
MVM Objects contain truly common properties that any view can bind to
VVM: This is almost a 1-to-1 replication of a WPF view
These objects are typically never shared outside its own view
The separation into MVM and VVM helps prevent a single view model class from catering to ever views' needs (ie. whole bunch of Is(Selected|Checked|etc) and *Command, that may be only used exclusively by one view).
(For some people, VVM logic could probably be part of the View. But for me, I often find myself eventually wishing I had separated them in the first place, for testing. So now I do.)
As the application evolves, properties/methods can be either pushed from the MVM into the VVM, or vice versa.
The application's hierarchy is almost never truly static.
Even when you build the best version of the application possible, the client will simply want more.
Having the know-how to refactor an existing architecture to accommodate new requirements > Designing an architecture that is flexible enough for any future requirements
having said all that, for many applications that aren't too complex, a slightly-bulgy View Model is usually good enough.
I'm trying to learn MVVM and WPF and I'm using the MVVM Light Toolkit. Here's what I'm not fully understanding and maybe it's due to an incorrect architecture of my UI.
What I'm trying to accomplish is pretty simple actually. This is a utility application by the way. I want a window that serves as the 'controller' so-to-say that has a set of buttons. Each button should change the content of a frame. Example: one button loads a 'screen' ( or a 'view' if you will ) that allows the user to configure an 'Agency' which is a custom object. Another button loads a list of Users from the Agency that was in the first 'screen'. This 'Users' view needs to also be loaded in the same frame. In fact, as of right now, the window with all the buttons really is only responsible for loading the 'screens' in the frame. The meat of the application will be within all the separate 'screens'
What I am not understanding is 1) how to let each screen/view know about each other since one is dependent upon the other. It seems that in MVVM the ViewModel shouldn't know about anything. But in my case, I need to pass information around ( such as my Agency ).
If I can get some hints on what I need to look into, that would be great.
Thanks!
Some ideas that might connect some of the dots:
You'll most likely have one viewmodel per view ("screen").
Each viewmodel will contain all of the logic for its corresponding view
Viewmodels can and will know about the models (Agency, Users)
Viewmodels can communicate with each other via the Messenger in MVVM Light
Think of MVVM Light's Messenger as an "application-wide eventing system". When you send a message out from one view model, any other view model can be listening for that message/event and react to it as needed.
Does that help at all? Keep your thoughts coming and I'll keep commenting and I'm sure the community will as well :)
Few things:
each of your screens, should be separate view (eg. user control or new window - I suppose you've done that already)
every part of model (eg. Agency, User) you want to display in your application, should be wrapped with its dedicated view model
your views don't really need to know about each other; you can use commands or events on view models to get rid of those dependencies
view model only needs to know about one thing: model it's building on
it's good to think about view as really simple class, with one single responsibility of rendering content; no logic, no code behind (unless it's purely UI/display related) is something to follow
You can try to prepare your models first (if you haven't done that already), then make view models for them (thinking what properties of models you want to expose to views) and once that's ready, build your views basing on view models. Other way around is also viable option - pick whichever feels more natural to you.
One more thing: since you mentioned you can display several screens in one (I assume) main area, think about equipping your view models with something along the lines of bool IsCurrentlyActive property. This way, you can easily show/hide views with button clicks and still utilize binding mechanism.
They shouldn't know about each other. That is what the Messenger is for controllers and views subscribe to the events they are interested in. That way they don't need to know or care where they event originated.
Hmm Kendrick is faster. What he said.
Also it sounds like you kind of want an Outlook type interface, some navigation that loads other views. I had the same question a while ago. How to do Regions in WPF without Prism?
To better understand the MVVM pattern look at this article: WPF Apps With The Model-View-ViewModel Design Pattern
Also I advice you to look at Caliburn Micro framework.
I'm trying to create an silverlight application using the MVVM design pattern. It's a kind of bank application.
I've watched a lot of tutorials on MVVM but something makes me real confused.
I have about fiwe usercontrols representing my views "TransactionsView", "AccountView" etc and a bunch of models "UserProfile" - containing user password, username and a list of UserAccounts, "UserAccounts" - containing name, balance and a list of AccountTransactions, "AccountTransactions" - containing a name, and ammount.
Should i create one modelview which contains my userprofile or should i create a viewmodel for every view i have? I'm a doing right so far? Or have i got it completley wrong?
Thanks
In MVVM, ViewModels are usually 1-to-1 with Views. There isn't a parity between number of ViewModel and Models, though.
View: UI
ViewModel: Handles changes to view state, forwarding them to the model if/when appropriate. Sends notifications from the underlying program back to the user. It may also do initial UI validation.
Model: Actual "guts" of the application. Algorithms, data storage, system calls etc go here. I put program flow here. I've seen other people put it in the ViewModel. That part is up to you to figure out.
A View always needs a ViewModel, hence 1-to-1 (it could have sub-models, but I'll leave that up to you to decide on/deal with. I'd start off with 1-to-1).
A ViewModel usually needs Models to actually "do work", but how many classes/instances is up to each app/problem you're trying to solve.
From what you explain you are going in the right direction. What viewmodel you create is a bit up to you, MVVM is not set in stone - its just a method. What I found through trial and ERROR was that it was smart to understand it well before digging myself in too deep.
I read many articles that didn't explain MVVM in a way I could understand. Finally I found a couple of articles by Jeremiah Morrill that were straight to the point and easy to understand: Article 1 and article 2.
One ViewModel per view is recommended for MVVM.
There's no real hard and fast rules but essentially there's normally one ViewModel per View. You can get into a situation where you want to share a view model across multiple views but it's rare.
Imagine what you want to see on the screen and each state the screen / controls on the screen might be in, everything that is needed on that particular screen (view) should have a corresponding property in your ViewModel that you can bind the View to. So, this translate to a single ViewModel for a particular View. The ViewModel itself can be tied into one or more model(s) in the back. At least that's how I understand it.
I am developing a large-ish application in WPF/WCF/NHibernate/etc. and have implemented the MVP pattern (although this question is still relevant to MVC) as the core architecture.
It feels quite natural to extend and add functionality as well as to come back and make changes on certain bits and pieces, as far as the core architecture is concerned (controllers, views, etc).
But at times the code-behind-ness of custom user controls that I create feels as if it "breaks" the MVC/MVP paradigm implemented, in that code concerns leak in the design and design concerns leak in the code. Let me clarify again, this is only for user controls. It is my personal opinion that this code-behind model (for both ASP.NET and WPF) is a 'Bad Thing', but no matter what my opinion, I'm stuck with it.
What are your recommendations for best practices in such a scenario? How do you handle such concerns? Do you for instance work around the code-behind-ness of custom controls and if so how??
Since you are using WPF, you should really look into the MVVM (Model-View-ViewModel) pattern. It is a form of the Presentation Model (PM) pattern discussed by Martin Fowler. WPF is very binding-oriented, and provides a very powerful and rich data binding framework for XAML. Using MVVM, you can completely and entirely decouple your ViewModels from your Views, allowing truly POCO UI development that offers the ultimate in separation of concerns and unit testability.
With MVVM, you will be able to modularize and decouple all of your views, including Windows, UserControls, etc., from the code that drives them. You should have no logic in Code Behind other than what is automatically generated for you. Some things are a little tricky at first, but the following links should get you started. The key things to learn are the MVVM pattern itself, Data Binding, Routed Events and Commands, and Attached Behaviors:
MVVM
Data Binding
Attached Behaviors
Attached Commands (VERY USEFUL!)
Routed Commands
Routed Events
WPF + MVVM has a bit of a learning curve up front, but once you get over the initial hurdle, you will never, ever want to look back. The composability, lose coupling, data binding, and raw power of WPF and MVVM are astonishing. You'll have more freedom with your UI than you ever had before, and you will rarely, if ever, have to actually bother with code behind.
I happen to like code-behinds (yet another personal opinion), but they work only as long as they do nothing but facilitate interactions between control events and the rest of the application. I'll admit that I've seen a lot of counter-examples, though. I even wrote a few of them....
Really, all the code-behind should do is "oh, someone clicked this button; there's probably something that wants to know about that." PRISM (from MS patterns and practices) provides a lot of architectural infrastructure for WPF and Silverlight; that includes a publish/subscribe interface that allows the controls and the code-behinds to simply publish an event while not even being aware of possible subscribers, or what the subscribers might do with the event. PRISM also adds commands for Silverlight.
A common variant of MVC for WPF and Silverlight is MVVM (Model, View, ViewModel). The ViewModel makes data available to the user controls in some form that is most useful (such as ObservableCollections, to facilitate two-way binding).
Custom Controls are there to display stuff. In that regard they are no different than a button or a drop down combo box. The trick is that don't let them handle stuff directly. They need to send stuff through the View Interface and the Presenter need to likewise interact with them through the view interface.
Think of it this way. If you ignored MVP the custom control would interact with the model in specific ways. what you doing with MVP is taking those way and defining them with the View Interface. Yes you are adding an extra call layer but the advantage is that you thoroughly document how it interacting with the rest of the system. Plus you get the advantage of being able to rip it out and replace with something entirely different. Because all the new thing needs to do is the implement it's portion of the view interface.
If you have a specific example I can illustrate better.