0

I created a MAUI application and in the view-model I have an ObservableCollection storing positions. Then these are displayed on the UI on a diagram. But the calculation of the positions takes a lot of time so I do it on another thread to keep the UI unblocked. When I calculate a position I add it to the collection on the new thread by invoking the Application.Current.Dispatcher.Dispatch method, like this:

Task.Run(() =>
{
    for (int i = 0; i < 1000; i++)
    {
         Application.Current.Dispatcher.Dispatch(() => 
         {
              myObservableCollection.Add(new Pos() { X = i, Y = i }));
         }
    }
}

It is working perfectly, but i want to avoid the constant thread switching in every iteration so I came up with this:

Task.Run(() =>
{
    List<Pos> test = new List<Pos>();
    for (int i = 0; i < 1000; i++)
    {
        test.Add(new Pos() { X = i, Y = i }));
    }
    Application.Current.Dispatcher.Dispatch(() =>
    {
        myObservableCollection= new ObservableCollection<Pos>(test);
    });
}

So i create the list and only pass it to the observable collection when it is ready to avoid thread switching. But this solution is not updating the UI at all and nothing appears meanwhile the first works perfectly. Why is the second one not working?

Rena821
  • 149
  • 7

3 Answers3

4

because your UI is bound to an instance of myObservableCollection - every time you create a new instance the binding to the old instance is still there and does not get updated.

there are several ways around this. The simplest is to implement INotifyPropertyChanged on your VM and call PropertyChanged in the setter of myObservableCollection

alternatively, you could use an ObservableRangeCollection which allows you do add multiple items to the collection at once

Jason
  • 86,222
  • 15
  • 131
  • 146
0

Now - with the MAUI Community Toolkit - you can simply declare an ObesrvableCollection which takes care of all the interface implementations for property changing under the hood

// From viewmodel
ObservableCollection<WhateverType> myObservableCollection; // as you would List<>
Jeff
  • 71
  • 7
0

Try:

[ObservableProperty]
private ObservableCollection<WhateverType> myObservableCollection;

or

[ObservableProperty]
private ObservableCollection<WhateverType> myObservableCollection = new();

I know one of them worked for me when I had this issue.