Event Aggregator with multiple views

Topics: Framework Services, Getting Started
Mar 20, 2014 at 2:54 PM
I'm trying to build this project using Caliburn for the first time (and also the MEF structure, that I didn't fully understand).

I need to use both the Conductor and the EventAggregator. The Conductor because i have an AppViewModel which "displays" 3 buttons that move the user to 3 different views (UserControls inside AppView).

And I need the EventAggregator because one of these 3 views has a button inside of it that must load 4th view (that must be a Window I think, not a UserControl, because it has to be full screen). So I thought that when the user click this button inside the 3 view (UserControl inside AppView) a Message can be sent top the listener (that should be the AppViewModel), and this one should ActivateItem(4th vm).

I don't why but even following the examples of the projects of Caliburn my message does not reach the AppViewModel.

This is my bootstrapper:
public class AppBootstrapper : Bootstrapper<AppViewModel>
    {
        private CompositionContainer container;

        protected override void Configure()
        {
            container = new CompositionContainer(new AggregateCatalog(AssemblySource.Instance.Select(x =>
                new AssemblyCatalog(x)).OfType<ComposablePartCatalog>()));

            CompositionBatch batch = new CompositionBatch();

            batch.AddExportedValue<IWindowManager>(new WindowManager());
            batch.AddExportedValue<IEventAggregator>(new EventAggregator());
            batch.AddExportedValue(container);

            container.Compose(batch);
        }

        protected override object GetInstance(Type serviceType, string key)
        {
            string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
            var exports = container.GetExportedValues<object>(contract);

            if (exports.Any())
                return exports.First();

            throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
        }

        protected override IEnumerable<object> GetAllInstances(Type serviceType)
        {
            return container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
        }

        protected override void BuildUp(object instance)
        {
            container.SatisfyImportsOnce(instance);
        }

        protected override void OnStartup(object sender, StartupEventArgs e)
        {
            DisplayRootViewFor<AppViewModel>();
        }
    }
This is the AppViewModel:
[Export (typeof(AppViewModel))]
public class AppViewModel : Conductor<object>, IHandle<ChangeViewEvent>
{
    [ImportingConstructor]
    public AppViewModel(IEventAggregator events)
    {
        events.Subscribe(this);
        ActivateItem(new MainViewModel());            
    }

    public void GoToPatientsManager()
    {
        ActivateItem(new PatientsManagerViewModel(new WindowManager(), new EventAggregator()));
    }

    public void GoToTestManager()
    {
        ActivateItem(new TestManagerViewModel(new WindowManager()));
    }

    public void GoToResultsManager()
    {
        ActivateItem(new MainViewModel());
    }

    public void Handle(ChangeViewEvent message)
    {
        switch (message.ViewName)
        {
            case "TestManager" :
                GoToTestManager();
                break;
        }
    }
}
And this is the view model that should launch the request for loading the 4th vm
 [Export(typeof(PatientsManagerViewModel))]
    public class PatientsManagerViewModel : Screen
    {
        private readonly IWindowManager _windowManager;
        private readonly IEventAggregator eventAggregator;

        [ImportingConstructor]
        public PatientsManagerViewModel(IWindowManager windowManager, IEventAggregator eventAggregator)
        {
            _windowManager = windowManager;
            this.eventAggregator = eventAggregator;
        }

        #region Methods

        public void ShowFakeMessage()
        {
            dynamic settings = new ExpandoObject();
            settings.Placement = PlacementMode.Center;
            settings.PlacementTarget = GetView(null);

            var res = _windowManager.ShowDialog(new DeletePersonViewModel(), null, settings);

            if (res)
            {
                // The result of the dialog men. In this true case we'll use Linq to delete the entry from the database
                // using the dbContext
            }
        }

        public void GoToTestManager()
        {
            eventAggregator.Publish(new ChangeViewEvent("TestManager"));
        }

        #endregion
    }
It does not reach the Handle method of the AppViewModel.

Is these something wrong with the instances of the view models? I can't move forward from here...
Is it becasue i create a new Event Aggregator evrytime I ActivateItem the PatientsManagerViewModel?

Thank you...