Problems with EventAggregator

Dec 23, 2010 at 11:33 AM

Hi one more time ^^

I have a viewmodel, that i changed [PartCreationPolicy(CreationPolicy.Shared)] to [PartCreationPolicy(CreationPolicy.NonShared)], to use the KeepAlive in my view. Thats ok,  but now i have a new problem, how can i pass my view model from the grid view to the Edit View (thats a childwindow) ?

I tryed the EventAggregator but recive an exception:

1 - thats my view model:

 [Export]
    [PartCreationPolicy(CreationPolicy.NonShared)]
        public class LinhasViewModel : ViewModelBase<Linha>
    {
        private HeaderGridControl _headerGrid;// = new HeaderGridControl();
        private IEventAggregator _eventAggregator;

        [ImportingConstructor]
        public LinhasViewModel(IDataService dataService, IRegionManager regionManager, IEventAggregator eventAggregator)
            : base(dataService, regionManager)
        {
             _eventAggregator = eventAggregator;

            this.ScreenDescriptionSingular = "Linha";
            this.ScreenDescriptionPlural = "Linhas";
            this.EditViewName = "LinhasEdit";

            InitializePermissions("Linhas");
         }

.......
// Thats my Edit Command
        public override void EditCommand(object sender, EventArgs e)
        {
            LoadEntities(() =>
                             {
                                 IsNew = false;
                                 CurrentItem = SelectedEntity;

                                 // Behavior that call an Edit window  
                                 ShowEditWindow(typeof(ILinhasEditWindow), EditViewName);

                                 _eventAggregator.GetEvent<EditLinhasEvent>().Publish(this);
                             });
        }

 

2 - My Event

    public class EditLinhasEvent : CompositePresentationEvent<LinhasViewModel>
    { }

 

3 - my edit windows

   [Export(typeof(ILinhasEditWindow))]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    [RegionMemberLifetime(KeepAlive = false)]
    public partial class LinhasEdit : UserControl, ILinhasEditWindow, IContentTitle
    {
        private LinhasViewModel _linhasViewModel;
        private IEventAggregator _eventAggregator;


        [ImportingConstructor]
        public LinhasEdit(IEventAggregator eventAggregator)
        {
            InitializeComponent();
            _eventAggregator = eventAggregator;

            Loaded += (s, o) =>
                          {

                              EditLinhasEvent evt = eventAggregator.GetEvent();

                              // Get ERROR HERE  
                              evt.Subscribe(EditLinhasEventSubs);

                              dataForm.CurrentItem = _linhasViewModel.CurrentItem;

                              dataForm.BeginEdit();
                          };

        private void EditLinhasEventSubs(LinhasViewModel model)
        {
            _linhasViewModel = model;
        }
4 - Error message
Attempt by method 'Microsoft.Practices.Prism.Events.DelegateReference.TryGetDelegate()' to access method 'Art.Solution.Module.Shared.Views.Edit.LinhasEdit.EditLinhasEventSubs(Art.Solution.Module.Shared.ViewModels.LinhasViewModel)' failed.
What am i doing wrong?
Dec 23, 2010 at 12:16 PM

My fault ^^

Found the Solution.

 private void EditLinhasEventSubs(LinhasViewModel model)
        {
            _linhasViewModel = model;
        }

That method need to be public

 public void EditLinhasEventSubs(LinhasViewModel model)
        {
            _linhasViewModel = model;
        }

 

 

Developer
Dec 23, 2010 at 1:25 PM

Hi Luciano,

I'm glad that you've found a solution to your problem. Thanks for sharing your findings with the community!

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Mar 19, 2013 at 10:40 AM
To anyone that has come across this problem

I had the same problem today. The subscribing method need not be made public. Another (and in my case better) option was:

ea.GetEvent(Of CustomerSelectedEvent).Subscribe(AddressOf Me.test, True)

That second boolean specifies that you wish to keep the subscriber reference alive. This fixed the issue.

Kurren.
Developer
Mar 19, 2013 at 5:17 PM
Hi,

Just to add some light to this topic, here is a note contained in the Prism documentation regarding some "requirements" to take into account when using the EventAggregator:

From Chapter 9 - Communicating Between Loosely Coupled Components - Subscribing to Events:
Due to Silverlight's security model, the methods supplied to Subscribe must be publicly accessible methods if you want a weakly-held subscription (which is the default CompositePresentationEvent behavior). Because lambda expressions and anonymous delegates are generated as private classes and methods, these cannot be used in conjunction with weak subscriptions. Instead, you will either need to use public methods or subscribe to the event with a keepSubscriberReferenceAlive option to force a strongly-held subscription (see example below).
'
Hence, if you wish to use weakly-held subscriptions your method needs to be public. However, when using strongly-held subscriptions you can use private / protected methods but you will need to unsubscribe manually from the event in order to prevent memory leaks.

Regards,

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