Assume a viewmodel for hosting a collection of item viewmodels. There can be some hundreds of items in the collection. The items are part of the business model and have an id and a name. The name for a specific item can be changed somewhere in the application and the viewmodel in the collection needs to be notified to refresh the property:
public interface IItem
{
Guid Id { get; }
string Name { get; }
}
public class ItemModel : ViewModelBase
{
private IItem _item;
public ItemModel(IItem item)
{
_item = item;
}
public void Refresh()
{
RaisePropertyChanged(nameof(Name));
}
public Guid Id { get { return _item.Id; } }
public string Name { get { return _item.Name; } }
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set { Set(ref _isSelected, value); }
}
}
public class ListModel : ViewModelBase
{
public ListModel(IEnumerable<ItemModel> items)
{
Items = new ObservableCollection<ItemModel>(items);
}
public ObservableCollection<ItemModel> Items { get; }
}
I have tried the following solutions, but i am not sure what the best one is:
register every item at creation and let the messenger always notify them all
public class ItemModel : ViewModelBase { public ItemModel(IItem item) { _item = item; MessengerInstance.Register<NotificationMessage>(this, (msg) => { if (msg.Notification == "REFRESH" && IsSelected) { Refresh(); } }); } [...]
register / unregister messenger on selection, so there will be only one viewmodel be registered
public class ItemModel : ViewModelBase { [...] public bool IsSelected { get { return _isSelected; } set { if (Set(ref _isSelected, value)) { if (value) { MessengerInstance.Register<NotificationMessage>(this, (msg) => { if (msg.Notification == "REFRESH") { Refresh(); } }); } else { MessengerInstance.Unregister<NotificationMessage>(this); } }; } } }
register the hostig viewmodel and iterate over the items, so there wil be only one registration too
public ListModel(IEnumerable<ItemModel> items) { [...] MessengerInstance.Register<NotificationMessage<Guid>>(this, (msg) => { if (msg.Notification == "REFRESH") { var item = Items.Single<ItemModel>(x => x.IsSelected); item.Refresh(); } }); }
which solution would you prefer? register and unregister on every selection or having hundereds of viewmodels registered to the messenger or itereate the items yourself? maybe there is also a better solution?