0

I have WinForms with WPF UserControl.

public partial class DynamicMediator : Form
{
        public DynamicMediator()
        {
            InitializeComponent();
            lmDynamicMediator = new LMDynamicMediator.MediatorMainWindow();            
            this.elementHost1.Child = this.lmDynamicMediator;
        }
        public MainWindowViewModel GetEditFormViewModel()
        {
            return lmDynamicMediator.Resources["ViewModel"] as MainWindowViewModel;
        }
}

I start a new process in my ViewModel after that I need to update my observableCollection in ViewModel I use

Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => HasListMessages.Add(item)));

but I have exception like this

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

if I use code like this

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => HasListMessages.Add(item)));

I have exception like this

System.Windows.Application.Current.get returned null

What I do wrong?

How I can get System.Windows.Application.Current in my ViwModel

Bizarre
  • 3
  • 2
  • 1
    Since this wpf is in a control library and your entry point is winforms, you will likely have no application at all to have a dispatcher. You will need the dispatcher from your UI. – Andy Jan 27 '23 at 11:35
  • If clemens approach somehow does not suit ( can't imagine why that would be though ) You could take a look at https://stackoverflow.com/questions/2091988/how-do-i-update-an-observablecollection-via-a-worker-thread – Andy Jan 27 '23 at 11:52

1 Answers1

3

Calling Dispatcher.CurrentDispatcher in a thread that is not yet associated with a Dispatcher will create a new Dispatcher, which is not the Dispatcher of the UI thread.

Use the Dispatcher of the thread in which the view model instance is created. Keep it in a field of the view model class

public class MainWindowViewModel
{
    private readonly Dispatcher dispatcher;

    public MainWindowViewModel()
    {
        dispatcher = Dispatcher.CurrentDispatcher;
    }

    ...
}

and later use that field:

dispatcher.BeginInvoke(() => HasListMessages.Add(item));
Clemens
  • 123,504
  • 12
  • 155
  • 268