Using EventAggregator with Parameterless ViewModels

Topics: Prism v4 - Silverlight 4
Jul 2, 2012 at 4:21 PM
Edited Jul 2, 2012 at 4:25 PM

I'm trying to use EventAggregator to pass events between ViewModels.

The problem is that I want to code parameterless ViewModels.

The UICompositionQuicStart suggests to do:

    public class EmployeeListViewModel : INotifyPropertyChanged {
        private readonly IEventAggregator eventAggregator;

        public EmployeeListViewModel(IEmployeeDataService dataService, IEventAggregator eventAggregator) {
            if (dataService == null)
                throw new ArgumentNullException("dataService");
            if (eventAggregator == null)
                throw new ArgumentNullException("eventAggregator");

            this.eventAggregator = eventAggregator;

            // Initialize the CollectionView for the underlying model
            // and track the current selection.
            this.Employees = new PagedCollectionView(dataService.GetEmployees());
            this.Employees.CurrentChanged += new EventHandler(this.SelectedEmployeeChanged);
        }

        public ICollectionView Employees {
            get;
            private set;
        }

        private void SelectedEmployeeChanged(object sender, EventArgs e) {
            Employee employee = this.Employees.CurrentItem as Employee;
            if (employee != null) {
                // Publish the EmployeeSelectedEvent event.
                this.eventAggregator.GetEvent<EmployeeSelectedEvent>().Publish(employee.Id);
            }
        }

I'm not using the dataService parameter in my project, but I do need the event, how can I code it without using parameters in my ViewModel?

Developer
Jul 2, 2012 at 7:10 PM

Hi,

If your view model is not being resolved through dependency injection and you want to retrieve / resolve an instance from the container, a possible approach could be to use the ServiceLocator class to access the container. For example, if you want to retrieve the EventAggregator inside your view model, you could do something similar to this:

public class MyViewModel
{
    private IEventAggregator eventAggregator;

    public MyViewModel ()
    {
        this.eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();
    }
}

I hope you find this useful,

Damian Cherubini
http://blogs.southworks.net/dcherubini

Jul 2, 2012 at 9:32 PM
Edited Jul 2, 2012 at 10:01 PM

Don't I need to register something first to make the event available in the ServiceLocator object?, perhaps in the ModuleEmployees.cs class (Module Implementation)?

Developer
Jul 3, 2012 at 1:04 PM

Hi,

Based on my understanding, you should be able to retrieve the instance of the EventAggregator from the container like mentioned above, take into account that by default in the initialization process of a Prism application, this class is registered in the container and mapped to the IEventAggregator interface.

If you are interested, more information about the application initialization process can be found in the following chapter of the Prism documentation:

Also, remember to add a reference in your project to the Microsoft.Practices.ServiceLocation assembly, when using the ServiceLocator.

Regarding the handling of the events, once you create the event in one of your modules (e.g. like the EmployeeSelectedEvent.cs in the UI Composition QuickStart) you should be able to subscribe/publish to it using the retrieved instance of the EventAggregator.

Also, for more information on how to create, subscribe and publish to events, you could check the following section of the documentation:

Regards,

Agustin Adami
http://blogs.southworks.net/aadami

Jul 3, 2012 at 1:39 PM

Thank you or answering