I am using Simple MVVM Toolkit in WPF to create an application, the application uses a central tab control, with a View (UserControl) for each tab item. These Views may also contain tab controls themselves containing further "sub-views".
Our difficulty is in finding a way to share application logic which is used by several of these views, without having one global huge messy class..
I would not go with a huge class which holds everything. But I would have a central ViewModel which controls the overall state. Like the ShellViewModel. And I would let the viewmodels communicate and exchange information via Messenger (MVVM Toolkit light) or EventAggregator (Prism).
They offer way vie Publish/Subscriber Pattern to exchange information. And you can address them by implementing own message classes and pass payload along with it.
So you could have a global Message for Save all and every (Sub-)ViewModel could register to it and runs there own save method after receiving the message...
Prism
http://msdn.microsoft.com/en-us/library/ff921122(v=pandp.20).aspx
MVVM light
http://blog.galasoft.ch/archive/2009/09/27/mvvm-light-toolkit-messenger-v2-beta.aspx
Let me know if this helps...
Related
I have to convert a decent sized Winforms application into a WPF app following the MVVM pattern. I'm not sure what the best way to do this is.
The application is built around a third party map control.
Multiple windows: A main window that displays the map, and other windows that allow the user to change properties of the map (add layers, change styles, etc).
My plan was to create a viewmodel for each window, and have a base viewmodel containing the map control itself and any properties/methods that needed to be shared.
The main thing I'm not sure about is how to handle the map operations that are built into the control. For instance, there is a MapMouse_Down event. Normally I would just put this in the code behind if I wasn't following MVVM, and handle it there. Is that the correct way to handle this?
Normally I would just put this in the code behind if I wasn't following MVVM, and handle it there. Is that the correct way to handle this?
You could keep anything that is purely view related in the code-behind of the views but anything that is testable application logic should be implemented in view models. View-related stuff may for example be animations and any code that changes the behaviour or appearance of a control in some way, like for example setting some width or colour.
There are different ways to handle "events" in MVVM depending on what kind of controls you are using but you would generally defined commands in the view model and invoked these from the view. Please refer to this blog post for more information.
Having a separate view model for each different type of window is ideal.
View models should never contain controls. They should contain only abstractions of the controls. If all of your windows have mapping components, only then should your base window view model have an abstraction of the mapping control. (An example of the sort of abstraction I'm talking about: Imagine a view that where the user should enter a name. The view will have a TextBox which has a Text property. The view model will have a Name property. The view will bind the TextBox's Text property to the view model's Name property. Figuring out the right abstractions for larger applications is one of the challenges of MVVM.)
It's perfectly fine to have event handlers in your view if your controls don't support data binding or they don't have ICommand support. But the event handler in your view should do as little as possible, instead just transferring control over to your view model, which will update its abstract representation of the view, which the view will then re-synchronize to through data bindings or manual synchronization logic.
WPF is different for Winforms, the approach is based on the binding of proprety .
Below an Example of using MVVM.
Easy MVVM Example
This is a basic process that I cannot find any info on in Google or reference books on my Kindle account.
In regular forms applications pre-Windows 8, if you are on form 2 and you want to update something on form 1, you just type:
form1.Default.controlOnForm1.text = "updated text";
This does not work in Windows 8.
Thank you.
UPDATE:
I found an easy way to do this in cases when databinding does not do what I need. I simply create a static copy of the control I need to access. Say Button1 on page2 needs to be accessed on page1.
At the top declare:
public static Button statButton1;
in the loaded event I create the relationship between the static copy and the button in the XAML code:
statButton1 = Button1;
And then easy as pie, you can access the button anywhere:
page2.statButton1.Width = 48;
Windows 8 apps (or any other XAML based apps) are usually made using the MVVM Pattern. I really recommend you read about it and do the same. This pattern leads to less coupling in the application and makes it easier to develop and maintain.
The type of changes you are talking about here would be done by setting a property on the ViewModel (VM), that in turn, notifies the View (UI) with a PropertyChangedEvent so it can refresh itself.
To allow the ViewModels to set each others properties, they would all need to know about each other, which in turn leads to high coupling. This is usually solved by using an EventAggregator or MessageBus which sends messages/events between objects (without them knowing about each other) based on a subscribe/publish pattern.
To start out I would look at An Address Book Application Made in MVVM for Metro. This is a basic example which shows the usage of this pattern without any frameworks.
Once you feel comfortable with the MVVM pattern, I would suggest you use a framework like Caliburn.Micro or MVVM Light. These frameworks offer lots of great stuff for building applications with the MVVM pattern.
I am developing a WPF MVVM Light application, I want to display some message boxes/dialog boxes or there are some other scenarios where I want my View model to communicate with its view or raise some event on its respective view.
How could I achieve that?
See Messenger class of MVVM Light. It should even have sample by default when you downloa MVVM light. It's something like Messenger.Default.Send(new YourMessageClass()) and you can register listener on View side.
The prism framework has a concept of interaction requests to solve this problem. A nice example can be found here or here.
The responsibility of displaying the popup should not be the ViewModel's responsibility, but a "service that takes care of it for you".
If the "popup window" is a modal like window like a "file open dialog", "file save dialog", message box "ok/cancel" or "yes/no" etc, then I believe that a "service" would be the right choice. The reason is that the service can be facked/mocked for unit testing.
Also, you can have different implementations of this service based on whatever you want: in debug (r, when the role is of type admin or developer) you have more "verbose" information than in release or regular users, for example.
Now, for "how does a ViewModel communicate to the View", I'm not sure what you mean. Simply add a property on the ViewModel and bind the view to that property.
I'm working on a windows 8 metro-style app, using developer preview for an academic project at university. We have to use MVVM pattern.
In the main Page we have a metro-style main menu with buttons. Each button leads to an application facility (ie. 'Show my Library', 'Show Favourites', ...) which should belong to a different View, according to MVVM pattern.
In your opinion should we create a new 'metro-style Page' for each View or expect a 'Scenario' for each use case refreshing the main Page, like those present in many example apps?
In other terms, using MVVM should there be a 1:1 match between 'plain old WPF Windows' and 'brand new metro-style Pages'?
The thing with MVVM is that there are no hard rules as to what constitutes a View other than the fact that it is the means by which the user can view the ViewModel data.
A View need not be a Page, but can be a Control. Thus you can have one page, on which many View controls are displayed, if you wish. Quite often I have my Views as controls, even if they are to be the sole item displayed on a page, as it allows me to embed them in other pages more easily at a later date.
The MVVM pattern is purely a means of separating the UI from the business/code logic. A ViewModel class doesn't care how it's data is displayed, it just provides the binding points, properties etc., for the data to be displayed and trigger points for code function.
Some people will insist that there is never any code in the code behind files, but I think that a more pragmatic approach is required. Code that controls visual aspects of the View is fine, and there are occaisions when what appears to be business logic intrudes.
For example when implementing drag and drop functionality code will be required in the code behind. This is really just a visual aspect so no problem there, but if the business model dictates that only certain items, or a maximum number of items are dropped in a given location then the ViewModel will need to provide some data binding points that the View can use to implement this. By doing so you could argue that the View code behind now implements some business logic.
So back to your original question. I would try to implement the application such that it behaves as is expected for a windows 8 metro-stryle application. This will obviously have a bearing on how you code, but it should still be possible to stick to the MVVM pattern when doing so.
I'm trying to create a strategy for handling popup forms for use throughout any part of my application. My understanding so far is that I will need a single UserControl in the root of my MainWindow. This will be bound to its own ViewModel which will handle the messages that are sent within the app.
I'm using MVVM Light, and I'm fairly new to the Messenger class.
Imagine a Master/Details scenario, where a list a objects are contained within a ListBox. Selecting one of these items and clicking an Edit button would display a UserControl which covers the whole screen. The user can then edit the selected item, and click OK to commit the change.
I want the UserControl that is opened to be "generic" in a way that I can throw any (probably a ViewModel) at it... for it to render the ViewModel via a DataTemplate and handle all the object changes. Clicking OK will callback to the sending class and persist the change as before.
Some situations where this would be useful are...
Display error messages with no required user input (other than OK to close it)
Display an edit form for a data item
Confirmation dialogs (much like a standard MessageBox)
Can anyone provide any code samples of how I might acheive this?
When designing a UI with MVVM the goal is to separate the concerns of the View from the concerns of the ViewModel. Ideally, the ViewModel should not rely on any view components. However, this is the idal and another rule of MVVM is that you should design your application as you wish.
In the area providing a service showing dialogs there are two different approaches floating arround:
Implementing the DialogService on the View (e.g. see http://geekswithblogs.net/lbugnion/archive/2011/04/13/deep-dive-mvvm-samples-mix11-deepdivemvvm.aspx Sample 03).
Implementing a service component that does is not attached to the view (e.g. see http://blog.roboblob.com/2010/01/19/modal-dialogs-with-mvvm-and-silverlight-4/)
Both approaches rely on an interface that defines the functionality the service provides. The implementation for this Service is then injected into the ViewModel.
Also, do both approaches have their specific advantages and disadvantages.
The first approach works also well for WP7, however, it requires a common view base class as this contains the implementation of the view service.
The second approach works well for SilverLight and WPF and appleals as it keeps the service separate from the view and does not impose any restictions on the view.
Another possible solution is to use messaging to show the dialogs.
Whatever approach you are using try to keep the View and the ViewModel de-coupled by using an IoC (inversion of control) pattern, i.e. define an interface so that you can use different implementations. To bind the services into the ViewModel use injection, i.e. passing the service into the constructor of the ViewModel or by setting a property.
I recently started learning MVVM for a WPF app I was creating, I used this article as a basis for showing dialogs, if you download the sample project then it is actually quite a nice decoupled method, it is nicely abstracted and to get a view you pass an instance of a viewmodel. I extended it somewhat for my own means, I also used the WPFExtendedToolkit MessageBox for warnings, errors etc because the standard win32 MessageBox is fugly.
With regards to dynamic forms then you'll want to investigate the ItemsControl, and in your ViewModels have a Collection of Data Items which need to be edited by the user for the ItemsControl to bind to. I have a dialog for editing actions and their parameters in a workflow system designer where the dialog list of actions was totally dynamic. This was done by exposing a collection of my items with their data types so I could then use a DataTemplateSelector to select DataTemplates which contained the correct types of controls, i.e. a datatype of DateTime showed a DatePicker.
Hope That Helps
From the perspective of a developer coming in to 'maintain' that generic code, it sounds like a pain. From what you've described, I would give the form and the dialog the same view model and create a specific XAML template for the dialog that you want to show.