I try to use EventAggregator between 2 viewmodel. However I don't know how to create singleton class to connect between 2 ViewModel
I refer this articles to write a example for me
https://www.codeproject.com/Articles/812461/Event-Aggregator-Pattern
My screenario is when I click on each item on listview, detailListView show detail item
Here is my code
Item.cs
public class Item
{
public Item() {}
public int Id { get; set; }
public string Name { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
}
ListViewModel.cs
internal class ListViewModel
{
protected readonly IEventAggregator _eventAggregator;
public ListViewModel(IEventAggregator eventAggregator)
{
this._eventAggregator = eventAggregator;
this.Items = new List<Item>();
this.Items.Add(new Item { Id = 1, Name = "Item A", Price = 100.00, Quantity = 250 });
this.Items.Add(new Item { Id = 2, Name = "Item B", Price = 150.00, Quantity = 150 });
this.Items.Add(new Item { Id = 2, Name = "Item C", Price = 300.00, Quantity = 100 });
}
public List<Item> Items { get; private set; }
private Item _selectedItem;
public Item SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
//Publish event:
this._eventAggregator.PublishEvent(_selectedItem);
}
}
}
DetailsViewModel.cs
public class DetailsViewModel : INotifyPropertyChanged
{
protected readonly IEventAggregator _eventAggregator;
public DetailsViewModel(IEventAggregator eventAggregator)
{
this._eventAggregator = eventAggregator;
_eventAggregator.SubsribeEvent(this);
}
private Item _item;
public Item Item
{
get { return _item; }
set { _item = value; NotifyPropertyChanged("Item"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
ListView.xaml
<Grid>
<ListBox ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
ListView.xaml.cs
public partial class ListView : UserControl
{
public ListView()
{
InitializeComponent();
DataContext = new ListViewModel(ApplicationService.Instance.EventAggregator);
}
}
DetailsView.xaml
<Grid>
<ContentControl Content="{Binding Item}">
<ContentControl.ContentTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Id: " FontWeight="Bold" Grid.Row="0"/>
<TextBlock Text="Name: " FontWeight="Bold" Grid.Row="1"/>
<TextBlock Text="Price: " FontWeight="Bold" Grid.Row="2"/>
<TextBlock Text="Quantity: " FontWeight="Bold" Grid.Row="3"/>
<TextBlock Text="{Binding Id}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="{Binding Name}" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="{Binding Price, StringFormat=c2}" Grid.Row="2" Grid.Column="1"/>
<TextBlock Text="{Binding Quantity}" Grid.Row="3" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
DetailsView.xaml.cs
public partial class DetailsView : UserControl
{
public DetailsView()
{
InitializeComponent();
DataContext = new DetailsViewModel(ApplicationService.Instance.EventAggregator);
}
}
And finnaly singleton class to connect 2 ViewModel
ApplicationService.cs
internal sealed class ApplicationService
{
private ApplicationService() { }
private static readonly ApplicationService _instance = new ApplicationService();
internal static ApplicationService Instance { get { return _instance; } }
private IEventAggregator _eventAggregator;
internal IEventAggregator EventAggregator
{
get
{
if (_eventAggregator == null)
_eventAggregator = new EventAggregator();
return _eventAggregator;
}
}
}
I don't know how to create _eventAggregator = new EventAggregator(); There is no EventAggregator() in Gautham Prabhu K's article.