MVVM firing event back to view - silverlight

I have a ViewModel where one of its functions is to talk to a service and get some data. However, if there is a problem, I would like a notify the user that the service could not run.
Currently what I am doing is firing an event which the view has subscribed to (my viewModel is created in the resources section of the view) and receiving the event in the view event handler I just do a Windows.Alert().
First, I am trying to reduce the amount of code in the code behind of the view and with the event firing, there must be a better way to do this?
Secondly, since my view knows about my view model (i.e. created in the resources section), I am sure this will cause problems in testing my view. Is this the correct way to do this?
JD.

Yes, I don't think subscribing to an event in the VM from the View is a good idea. Almost better to put the alert in the VM, but that puts UI in the VM and makes it hard to test. There are a couple of other ways to handle this.
Dialogs and ViewModel - Using Tasks as a Pattern
Decoupled ChildWindow Dialogs with Prism in Silverlight 3

Best to use a service here. A service just provides some function through an interface.
public interface IDialogService {
void ShowNotifictation(string message);
}
The ViewModel takes this service and uses it to display the notification. The implementation of this service is then specific to your solution, and can display the notification however you want.

The implementation of such a service might look like this:
[Export(typeof(IMessageService))]
public class MessageService : IMessageService
{
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
...
It uses MEF as IoC Container. The service is registered via the Export attribute as IMessageService.
You might have a look at the WPF Application Framework (WAF) to see the full implementation and sample applications that are using this service.
Hope this helps.
jbe

Related

Service call from MVVM

Which is the right place to call service in MVVM pattern, View Model or Model? I am planning to invoke service from ViewModel, get the JSON and convert it to corresponding model.
The reason I am not invoking service from Model to keep the Model decoupled from service.
Is this approach right or I should call service from Model?
Typically VM is responsible for making service calls. A sample call stack can be:
UI Event (View) => ICommand Execute (VM) => Service Call (VM).
It's advisable to have a re-usable Service Tier utilising the same domain objects as your app - as it allows the service-calling logic to be shared by multiple VMs (added from comments).
I think that the right place for calling a service is in Model.
The reason I am not invoking service from Model to keep the Model decoupled from service
So in this case you have your ViewModel which should handle presentation logic coupled with Service calls that probably involve data validation or manipulation.
According to
5: Implementing the MVVM Pattern Using the Prism Library 5.0 for WPF
The View Model Class:
It encapsulates the presentation logic required to support a use case or user task in the application. The view model is testable independently of the view and the model.
The view model typically does not directly reference the view. It implements properties and commands to which the view can data bind.
The view model coordinates the view's interaction with the model. It may convert or manipulate data so that it can be easily consumed by the view and may implement additional properties that may not be present on the model.
The Model Class
Model classes are non-visual classes that encapsulate the application's data and business logic. They are responsible for managing the application's data and for ensuring its consistency and validity by encapsulating the required business rules and data validation logic.
The model classes are typically used in conjunction with a service or repository that encapsulates data access and caching.
And as the previous answer showed something like this:
UI Event (View) => ICommand Execute (VM) => Service Call (VM).
I think it should be more like this
UI Event (View) => ICommand Execute (VM) => Handle Command/Action (VM) => Execute business/data logic that VM Command should have triggered (M) => Service Call (M).
You can create some kind of service helper that can be called from various models if you want to reuse service access code.

Silverlight: Binding to data shared across viewmodels

I've created a class named JsData and instantiated it in App.xaml.cs so that I can access it from multiple viewmodels. The JsData has several ObservableCollections, some properties for configuration and some methods which manipulate the process of automatically pulling data from remote server.
Now comes the question. Is it convenient for me to bind the global data to my views with minimum coding? Besides, I'm using Caliburn.Micro. Is it doable and appropriate to notify PropertyChanged events to viewmodels using messaging?
I think the best way to do this is to create a service that your view models can implement. That way on,y the view models that need the data can implement the service, and the service is more flexible because it can be injected in the view model construction. This keep your view models more decoupled and honors the mvvm pattern.
I would not use messaging to not notify changes, that would create unnecessary overhead. You just need to have your view model implement inotifypropertychanged and then get the service in your constructor And then pass the service values to properties in your view model that raise the property changed event.
If your need help defining a service just let me know and I will post a sample

WPF MVVM service layer

I plan on writing a WPF app following the MVVM pattern for the first time but something is not quite clear to me. Let's say that the view has a "Save" button and when that is hit I need to save the current state of my data (the model). This will be done by sending a SOAP message to a SOAP service.
Where in my MVVM setup do these SOAP request/response handlers live? Does the view model make the SOAP call itself whenever the save button is hit? Should the view model notify the model to save itself instead? Maybe it's some other way, completely separate from the MVVM?
My thinking was that (at least in this specific case) the view model would handle it since it needs to disable the save button in the view until the current save request has completed.
I typically put a logical client-side application/business layer between the viewmodel and the SOAP/WCF/Webservice layer. This layer is where all the non-view business logic and processing logic lives. Remember, the viewmodel is the model of the view, not the model of the domain. Therefore, you want to hand off control to the next layer down ASAP.
In this scenario, I would have the view trigger a save command on the the viewmodel, which would in turn call into the application layer, which would in turn make any calls to remote services.
The ViewModel, should not do such an operation. It only should trigger it. Therefore the model has to do it (or another intermediate layer that is responsible for the load-and save-operations, but not the ViewModel itself).
The ViewModel can observe the save-operation and may provide state-information about the progress for the View.
I would create a service handler that can be accessed by the ViewModel. Pass this into the constructor of the viewmodel, and call the methods exposed by the service handler.

Prism, Event published in shell not caught in module!

I have a wpf composite application with 3 or 4 modules that will always be loaded. In my shell I have a toolbar with buttons to active corresponding views from these modules. I injected an IEventAggregator into the shell presentor so that when a button is pressed I can publish an event that the corresponding module controller has subscribed to. When the event is caught the controllor will active its view.
Thats the theory anyways, in practice my controller is not catching the event. There are no errors in publishing or subscribing. I thought at first that there might be an issue with the eventAggregator not being the same, but thats not the case, and the event has a subscriber when its published.
Can anyone think of a reason why the event is not getting caught?
(Or any suggestions on a different way to get my view to show would be helpful too!)
Do you have your module controller 'alive'? Are you subscribing to the event using weak delegate reference or strong reference?
Seems that what is happening is that your module controller is being disposed, and so, the event is not getting caught.
To subscribe with a strong reference, use the keepSubscriberReferenceAlive option on the Subscribe method.
You can check the Event Aggregator article from the documentation which might provide more insight.
If that still does not works, can you share your repro code with me so I can take a look to it? (ezequieljadib at hotmail dot com)
Thanks,
Ezequiel Jadib

Redirection Between View In MVVM

I am using MVVM patern for developing my WPF application. It working fine for unrelated pages, means how to go in another view from one view.
Eg:
I have one list page in which some records are coming from one ViewModel and another from another ViewModel, means I have two ViewModel form my single View. And now I want to display another View by some event.
I am using IsSelected property for notification of changes. This mechanism works only upto when any action performed on same ViewModel, what should I do for such senario.
MVVM as a pattern is about separating concerns, improving testability of your code, etc.. so your ViewModel should only be concerned with applying business rules and providing data for your View.
You will need to use this in conjunction with some kind of MVC pattern, where the Controller's concern is handling the application navigation/state, etc.
(edit)
For example, imagine your app has a login screen, so you create a LoginView, which contains a username and password; probably an OK button and a Cancel button.
You create a LoginViewModel class to bind this view and handle the logic of the login within this class.
But once the app is logged in, it is not the responsibility of the login ViewModel to know where to go next; or which View to render next.. maybe you want to navigate to the last screen this user was on the previous time they were logged in? Maybe it goes to a default screen, as per the User's profile? This decision is nothing to do with the login function...
So if you create a Controller class, you can: Instantiate an instance of the LoginViewModel class, then depending on the login result, apply business rules as required to remove the LoginViewModel from scope, and create a new ViewModel, (e.g. HomePageViewModel) etc...
Finally, you'll need to let the app know which Views to use for each VM using DataTemplates
There are heaps of other ways to skin this particular cat, of course... this is just one idea...
As long as the core concept remains: Use MVVM to bridge the gap between View and Model in a clean, testable way... don't try and make it the 'one pattern fits all' :)
HTH :)
I agree with IanR to use a Controller for the workflow/navigation.
The ViewModel sample of the WPF Application Framework (WAF) shows how this might be done.

Resources