I have been trying to implement the prism EventAggregator in my MVVM Wpf application. I made this I'm about to show with inspiration from this blog post: Prism EventAggregator
The overall goal is sending a list to the other viewModel.
Have a ViewModel as a Publisher, where I'm trying to publish an ObserverableCollection.
Event class:
public class RoomsSelectedEvent : PubSubEvent<ObservableCollection<Room>>
{
}
I'm using Unity to inject the IEventAggregator interface, like:
Unity startup method:
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//view & viewModels
_container = new UnityContainer();
_container.RegisterType<IViewMainWindowViewModel, MainWindow>();
_container.RegisterType<IViewMainWindowViewModel, MenuViewModel>();
_container.RegisterType<IViewBookingViewModel, BookingView>();
_container.RegisterType<IViewBookingViewModel, BookingViewModel>();
_container.RegisterType<IViewContactViewModel, ContactDetailsView>();
_container.RegisterType<IViewContactViewModel, ContactViewModel>();
_container.RegisterType<IGetRoomsService, GetRoomsService>();
_container.RegisterType<IPostReservationService, PostReservationService>();
_container.RegisterType<IGetReservationsListService, GetReservationsListService>();
//types
_container.RegisterType<IEventAggregator, EventAggregator>(new ContainerControlledLifetimeManager());
_container.RegisterType(typeof(IDialogService<>), typeof(DialogService<>));
_container.Resolve<MainWindow>().Show();
}
In my publisher ViewModel, I'm creating the event.
Publisher ViewModel:
public class BookingViewModel : INotifyPropertyChanged, IViewBookingViewModel
{
//aggregator
protected readonly IEventAggregator _eventAggregator;
//commands
public ICommand ContinueCommand { get; set; }
public ObservableCollection<Room> RoomsList { get; private set; }
public ObservableCollection<RoomList> DropDownRooms { get; private set; }
public ObservableCollection<CustomerList> DropDownCustomers { get; private set; }
//enities
private readonly IDialogService<ContactDetailsView> _dialogServiceContactView;
private readonly IGetRoomsService _getRoomsService;
public BookingViewModel(IDialogService<ContactDetailsView> dialogServiceContactview, IGetRoomsService GetRoomsService, IEventAggregator eventAggregator)
{
// Injection
_dialogServiceContactView = dialogServiceContactview;
_getRoomsService = GetRoomsService;
_eventAggregator = eventAggregator;
//Instantiation
RoomsList = new ObservableCollection<Room>();
//Instantiation commands
ContinueCommand = new RelayCommand(ContinueCommand_DoWork, () => true);
}
// Continue Command
public void ContinueCommand_DoWork(object obj)
{
ObservableCollection<Room> RoomsSelected = new ObservableCollection<Room>();
ObservableCollection<Room> RoomsListNew = new ObservableCollection<Room>();
RoomsSelected = _getRoomsService.FilterSelectedRooms(RoomsList);
//Publish event:
_eventAggregator.GetEvent<RoomsSelectedEvent>().Publish(RoomsSelected);
_eventAggregator.GetEvent<RoomsSelectedEvent>().Subscribe((data) => { RoomsListNew = data; });
// Open new dialog
_dialogServiceContactView.ShowDialog();
}
}
On my Subscriber ViewModel, I need to retrive this list.
Subscriber ViewModel:
public class ContactViewModel : IViewContactViewModel, INotifyPropertyChanged
{
//aggregator
protected readonly IEventAggregator _eventAggregator;
//properties
public ObservableCollection<Room> SelectedRooms { get; set; }
public ContactViewModel(IEventAggregator eventAggregator)
{
//Injection
_eventAggregator = eventAggregator;
//Subscripe to event
_eventAggregator.GetEvent<RoomsSelectedEvent>().Subscribe(handleSelectedRoomsEvent);
_eventAggregator.GetEvent<RoomsSelectedEvent>().Subscribe((data) => { SelectedRooms = data; });
}
private void handleSelectedRoomsEvent(ObservableCollection<Room> room)
{
if (room != null)
{
SelectedRooms = room;
}
}
public ObservableCollection<Room> Rooms
{
get { return SelectedRooms; }
set { SelectedRooms = value; NotifyPropertyChanged(); }
}
}
When I debug, the handleSelectedRoomsEvent method is not even being called. Also the:
Subscribe((data) => { SelectedRooms = data; });
Here data and SelectedRooms is equal to null all the time. I can see in debug mode that an event is fired.
Hope someone can see what could be wrong here. Note: Using the prism.Core 6.1 version. (Have also tried prism version 5.0)
Good day!
Forgot to mention that in my view, I'm using a ListBox where the itemsSource should get the selectedRooms (the one I'm subscribing to)
<ListBox Foreground="#ffffff" Background="#336699" BorderBrush="#336699" ItemsSource="{Binding Rooms, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding RoomNumber}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding Beds}"/>
<TextBlock Text=" - "/>
<TextBlock Text="{Binding RoomType}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>