0

My label text isn't updating properly in my 3.5 WPF MVVM app. The do work part lasts long enough that you can see the waiting mouse pointer. All I ever see is "Parsed" in the label, which is Bound to InfoText. the Dispatcher and do work lines are in a Command's method. Ideas?

The code

Dispatcher.Invoke((Action<string>)SetInfoText, "Start Parsing");
//do work
 Dispatcher.Invoke((Action<string>)SetInfoText, "Parsed");

 private void SetInfoText(string text)
    {
        InfoText = text;
    }

  private string _infoText;
    public string InfoText
    {
        get
        {
            return _infoText;
        }
        set
        {
            _infoText = value;
            OnPropertyChanged("InfoText");
        }
    }
mike
  • 3
  • 3

2 Answers2

2

The only thing I can think of to explain it is that you're doing the work on the UI thread. This would prevent the dispatcher from redrawing until your work is done. The work being passed in Invoke is placed in the event queue, meaning it will be performed when idle.

The proper way to fix it is to do the work on a separate thread. If you're looking for workarounds though, look here. Reference: MSDN

EDIT: There are lots of ways to perform the work on another thread. Read up on BackgroundWorker, ThreadPool, Task Parallell Library, Threads. :) Here's a really simple way to do the work in a background thread:

     System.Threading.ThreadPool.QueueUserWorkItem( state => 
     {
        Dispatcher.Invoke((Action<string>)SetInfoText, "Start Parsing");
        System.Threading.Thread.Sleep(5000); // Simulate work
        Dispatcher.Invoke((Action<string>)SetInfoText, "Parsed");
     });
Community
  • 1
  • 1
Robert Jeppesen
  • 7,837
  • 3
  • 35
  • 50
  • Was just about to post this myself – AndrewS Mar 17 '11 at 04:05
  • how would I do this on another thread? simple as new thread();? – mike Mar 17 '11 at 04:37
  • it works, but now I've got issues with "This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread" – mike Mar 17 '11 at 11:46
  • the lines of code which alter your collection now has to be in Application.Current.Dispatcher.BeginInvoke(new Action(() => { //here goes your lines of code wich alter your collection};));, because the collection is assingned to the ui thread. but pay attention that you do not the long runing stuff in it, otherwise the ui in hangin again ;) maybe you should post your dowork code to give you better information – blindmeis Mar 17 '11 at 13:32
0
 Application.Current.Dispatcher.BeginInvoke(new Action(() => this.InfoText="Start Parsing"));

this works for me.

nevertheless i would put my long running process in a backgroundworker. so ui thread will not get blocked.

edit: if you do all your work in ui thread you should look at the overload for BeginInvoke - you can pass a DispatcherPriority. may be this helps too

blindmeis
  • 22,175
  • 7
  • 55
  • 74