Subscribe to an Event : failed

Topics: Prism v2 - WPF 3.5
Jun 16, 2009 at 11:44 AM

Hi,

I am trying to use the Event Pattern provided by Prism for my application. Unfortunately, I didn't succeed to subscribe to an event yet.

I am using singleton for my ViewModel (perhaps isn't a good thing for this stuff) but it seems that my eventAggregator knows that there is one event published but he couldn't catch it.

Here is my part of code :

<ViewModel>

   private MemberViewModel(IEventAggregator eventAggregator)
        {
            Model = new Member();
             ...
            _eventAggregator = eventAggregator;
        }
        public static MemberViewModel Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new MemberViewModel(new EventAggregator());
                }
                return instance;
            }

        }

 public void SelectionChanged(int? id)
        {
            _eventAggregator.GetEvent<MemberSelectedEvent>().Publish(id);
        }

<XAML.cs >

  private void ListMember_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            mVM.SelectionChanged(((Member)this.ListMember.SelectedItem).MemberId);
        }

 

And in another module :

  private ContratViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator;
            ...
            _eventAggregator.GetEvent<MemberSelectedEvent>().Subscribe(MemberSelected);
        }      

        public static ContratViewModel Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ContratViewModel( new EventAggregator());
                }
                return instance;
            }
        }      

 

         private void MemberSelected(int? Id)
        {
          //" some Stuff"
        }

 

<Infrastructure> //My event

 public class MemberSelectedEvent : CompositePresentationEvent<int?>
    {
    }

 

I don't know where I made a mistake.

Thanks in advance for your helps, BR

Nicolas

 

Jun 17, 2009 at 8:32 PM

Hi Nicolas,

 

I do not know your exact scenario, but I might be able to provide some ideas for this. If you are obtaining your MemberView’s ViewModel reference used to call this method:
private void ListMember_SelectionChanged(object sender, SelectionChangedEventArgs e)

        {

            mVM.SelectionChanged(((Member)this.ListMember.SelectedItem).MemberId);

        }

 

From here:

public static MemberViewModel Instance

        {

            get

            {

                if (instance == null)

                {

                    instance = new MemberViewModel(new EventAggregator());

                }

                return instance;

            }

        }

You are getting a new instance of the EventAggregator service (which might not be a good idea since services are usually singletons, so you should be sure that a new instance is required by your application). When you fire the event with that EventAggregator, there are no events subscribed. Something similar could be happening with the ContractView. When publishing/subscribing events, you should make sure that you are using the same instance of the EventAggregator service that is registered in the container.

 

You can achieve this in two different ways (that I can currently think of).

 

Use the ServiceLocator to get the EventAggregator singleton instance

1.       Add a reference to the Microsoft.Practices.ServiceLocationAssembly. It is located in the ~DecompressionFolder\LIB\Desktop\CommonServiceLocation path.

2.       Modify the line that creates a new instance of each of your view models for the following:

 instance = new ContratViewModel(ServiceLocator.Current.GetService(typeof(IEventAggregator)) as IEventAggregator);

 

Register your ViewModels as a singleton in the container

1.       Register your ViewModel as a singleton in the UnityContainer. You can check this article for information on how to achieve this.

2.       In your views, you can resolve your singleton ViewModel through Unity’s resolve method.

ViewModel vm = container.Resolve<ViewModel>();

 

You can check the following article from the documentation which might provide more insight:

·         Event Aggregator

 

You can also check out some of the following solutions that come with the Guidance, which use EventAggregator:

·         Event Aggregation QuickStart

·         Stock Trader Reference Implementation

 

Please let me know if this helps.

 

Damian Schenkelman

http://blogs.southworks.net/dschenkelman