0

I have such structure MainWindow where I call this method AddTaskBtnClicked from other class

partial class MainWindow: Window
{
...
    private void foo()
    {
       m_presenter.AddTaskBtnClicked();
    }
...
}

then my Presenter

public class Presenter{
...
        public ObservableCollection<string> TaskList { get; } = new ...;
        public void AddTaskBtnClicked() =>
            FactoryTask?.StartNew(() =>
            {
               TaskList.Add(...);
            }
...

And here in this line TaskList.Add(...); I get an error

System.NotSupportedException: 'This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.'

I understand that I can move this line in UI thread or don't call StartNew(), but problem is that I can't change it. I need somehow make it work, maybe with use of dispatcher. I found this answer on SO

https://stackoverflow.com/a/33343937/5709159

But problem is that all of these BindingOperations.EnableCollectionSynchronization, var uiContext = SynchronizationContext.Current; or Dispatcher.Invoke works just in class that inharite from UI (UserControl or Window).

So, question is - how to add item in Observable collection from other thread in class that doesn't inherit form UI ?

Sirop4ik
  • 4,543
  • 2
  • 54
  • 121
  • 1
    Why is the solution you've already posted not working? Since you are using static App, you don't need to inherit from UI components to do this. – Fruchtzwerg Nov 11 '20 at 18:37
  • @Fruchtzwerg when I wrote this line `App.Current.Dispatcher.Invoke(...` VS shows me that it doesn't know what `App` is. And offer to create local `App` var. But if I put this line somewhere in my `MainWindow` class it is ok. – Sirop4ik Nov 11 '20 at 19:02
  • Looks like you've not included the namespace of your App class? – Fruchtzwerg Nov 11 '20 at 19:09
  • @Fruchtzwerg I thought `App` class is some system class, no? How I need to include this namespace? – Sirop4ik Nov 11 '20 at 19:14
  • When you say you can't change AddTaskBtnClicked, both calling it from a Dispatcher Action, nor using BindingOperations.EnableCollectionSynchronization will help. While the former does not prevent that a background Task is started, the latter needs a lock object that must be used to synchronize access to the collection. – Clemens Nov 11 '20 at 19:19
  • That the collection is accessed from a type different from your window doesn't preclude the use of the standard mechanism for synchronization. The documented technique, explained in both duplicates and many other SO answers, works fine. You just need to make sure you set up the `EnableCollectionSynchronization` in your window's code. If you believe that still does not address your problem, post a new question that includes a [mcve] and makes clear why that synchronization doesn't work. – Peter Duniho Nov 11 '20 at 19:22

0 Answers0