I have a problem with ReactiveUI ObservableCollection. I am trying to update the UI based on a list that changes in a ReactiveObject, but for some reason my list change is not triggered and I am not sure what I am doing wrong.
There is a full repo here : https://github.com/SebiCiuca/ObserableCollection
App has a button, that when it's clicked calls a "RandomService" that removes items from a list and then adds a random number of items back into the list.
This list is an ObservableCollection that has a Subscribe on it, so I would like to see in my ViewModel that the list change happening in RandomService is triggering my ObservableCollection ModelList change.
Code below:
MainWindow
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
{
public MainWindow(MainWindowViewModel mainWindowViewModel)
{
InitializeComponent();
ViewModel = mainWindowViewModel;
DataContextChanged += (sender, args) => ViewModel = DataContext as MainWindowViewModel;
this.WhenActivated(cleanup =>
{
this.BindCommand(ViewModel, vm => vm.RandonListCommand, view => view.RandomButton).DisposeWith(cleanup);
});
}
}
MainWindowViewModel
public class MainWindowViewModel : ReactiveObject
{
private readonly IRandomService m_RandomService;
public ReactiveCommand<Unit, Unit> RandonListCommand { get; set; }
public MainWindowViewModel(IRandomService randomService)
{
m_RandomService = randomService;
RandonListCommand = ReactiveCommand.Create(() => { CallRandomService(); });
randomService.WhenAnyValue(rs => rs.ModelList).WhereNotNull().Subscribe(_ => TriggerUpdateUI());
}
private void CallRandomService()
{
Debug.WriteLine("Random is called");
var random = new Random();
var take = random.Next(1, 4);
Debug.WriteLine($"Take is {take}");
m_RandomService.UpdateList(take);
}
private void TriggerUpdateUI()
{
Debug.WriteLine("List changed");
foreach (var model in m_RandomService.ModelList)
{
Debug.WriteLine($"{model.Id} {model.Name}");
}
}
}
RandomService
public class RandomService : ReactiveObject, IRandomService
{
private List<RandomModel> _privateList;
public RandomService()
{
_privateList = new List<RandomModel>
{
new RandomModel { Id = 1, Name = "FirstRandom" },
new RandomModel { Id = 2, Name = "SecondRandom" },
new RandomModel { Id = 3, Name = "SecondRandom" },
new RandomModel { Id = 4, Name = "SecondRandom" }
};
_modelList = new();
}
private ObservableCollection<RandomModel> _modelList;
public ObservableCollection<RandomModel> ModelList
{
get => _modelList;
set => this.RaiseAndSetIfChanged(ref _modelList, value);
}
public void UpdateList(int take)
{
_modelList.Clear();
Debug.WriteLine($"ModelList count {_modelList.Count}");
var addToUI = _privateList.Take(take).ToList();
addToUI.Shuffle();
addToUI.ForEach(p => ModelList.Add(p));
Debug.WriteLine($"ModelList count {_modelList.Count}");
}
}
IRandomService
public interface IRandomService
{
ObservableCollection<RandomModel> ModelList { get; }
void UpdateList(int take);
}
From my point of view everything is correct if I read the definiton of ObservableCollection
"Represents a dynamic data collection that provides notifications when items get added or removed, or when the whole list is refreshed."
So my question is, why is my TriggerUpdateUI() never called. ( except at the start of the app when it's initialized).