7

I'm creating an application (an Office Add-in for Outlook)

The issue I have is updating my screen. I know I need to use invoke the Dispatcher but, it's always null in my ViewModel

    private ObservableCollection<string> _updates;
    public ObservableCollection<string> Updates
    {
        get { return this._updates; }
        set
        {
            this._updates = value;
            OnPropertyChanged("Updates");
        }
    }


        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += ((s, e) =>
        {
            //logic
            UpdateProgress("Finished");
        });

        bw.RunWorkerAsync();


    private void UpdateProgress(string s)
    {
        //Application.Current.Dispatcher.Invoke(() =>
       // {
        App.Current.Dispatcher.Invoke(() =>
        {            
            this.Updates.Add(s);
        //});
        });
    }

As you can see, I've tried 2 approaches, but Current is always null.

Oddly, if I use the same code in the code behind of my MainWindow then the following works fine

    private void UpdateProgress(string s)
    {
        Dispatcher.Invoke(() =>
        {
            this.Update = s;
        });
    }

I've read up, the reason is because the MainWindow code behind inherits from Window.

My question is, do I have to create a new Dispatcher object or is there something I'm missing. All I'm trying to do is update my GUI whilst the thread is running.

MyDaftQuestions
  • 4,487
  • 17
  • 63
  • 120
  • 1
    Application.Current should be null if you attempt to access it in a non-UI thread. You can save a reference to dispatcher in constructor as a field member then use it in a non-UI thread. – Mehrzad Chehraz Sep 22 '16 at 16:58
  • 1
    The normal entrypoint for a WPF is Main(). Which is auto-generated to create your App.xaml class instance, hard to see. The entrypoint is no longer Main() in an add-in, it is now you Startup event handler. So you have to create your app instance yourself. Boilerplate code [is here](http://stackoverflow.com/a/2694710/17034). – Hans Passant Sep 22 '16 at 17:09
  • @HansPassant, is there any way you can move this comment to an answer? – MyDaftQuestions Sep 23 '16 at 07:34
  • Just type up the answer in your own post, show what your Startup event handler looks like, and mark it as the answer. – Hans Passant Sep 23 '16 at 07:39

3 Answers3

3

Answered in comments by Hans Passant

The normal entrypoint for a WPF is Main(). Which is auto-generated to create your App.xaml class instance, hard to see. The entrypoint is no longer Main() in an add-in, it is now you Startup event handler. So you have to create your app instance yourself. Boilerplate code is http://stackoverflow.com/a/2694710/17034

Application.Current and App.Current is null

MyDaftQuestions
  • 4,487
  • 17
  • 63
  • 120
2

As a workaround you could maybe do the following:

public MainWindow()
{
  InitializeComponent();
  AppWindow = this; // Here you set the static member to reference this MainWindow.
}

public static MainWindow AppWindow
{
  get;
  private set;
}

And then in your viewmodel:

private void UpdateProgress(string s)
{
  MainWindow.AppWindow.Dispatcher.Invoke(() =>
  {
    this.Updates.Add(s);
    //});
  });
}
2

If you are trying to open a WPF application from a Winforms appliation, Application.Current is null. Application.Current is a feature of WPF applications only and not Winforms. You may try the below link:

Why does Application.Current == null in a WinForms application?

shruti singh
  • 146
  • 11
  • 1
    Don't ignore tags, winforms != wpf. Also on SO we are closing questions as duplicates rather than creating new answers with link to duplicated questions. – Sinatr Jan 14 '19 at 15:22
  • You need to read the reply completely. I was trying to to help this person from something I had earlier faced; and it was in WPF, since I was creating a WPF window from another Winforms app. Don't be keen to just down vote. Also, as far as closing is concerned, not everyone can close a question. You have the required points, hence you are able to. – shruti singh Aug 26 '19 at 11:40