0

User can perform an action and I add data to a collection that is bound to a DataGrid and that works fine.

But when there is a long running process that has multiple records added to the collection I never see the DataGrid updated until the process is over. What am I doing wrong? I am really new to this so I am sure the issue is something simple.

   private ObservableCollection<StatusEntry> _collSe = new ObservableCollection<StatusEntry>();
    public ObservableCollection<StatusEntry> CollSe
    {
        get { return _collSe; }
        set
        {
            _collSe = value;
           // NotifyPropertyChanged("CollSe");
        }
    }

  CollSe.Add(new StatusEntry() { TimeStamp = DateTime.Now, Comment = "STARTED: Translating file to DataTable" });
                DataTable dt = ExcelHelper.ReadAsDataTable(tbFileName.Text);
                CollSe.Add(new StatusEntry() { TimeStamp = DateTime.Now, Comment = "COMPLETE: Translating file to DataTable" });

EDIT:

More clearly here is what I tried.. Still does not update the UI until the end though

  private void btnProcessFile_Click(object sender, RoutedEventArgs e)
    {
        //THis should happen as soon as the button is pressed
        ThreadStart job = new ThreadStart(() =>
        {
            for (int i = 0; i < 20; i++)
            {
                // The new thread puts UI operations in the dispatching queue
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    CollSe.Add(new StatusEntry() { TimeStamp = DateTime.Now, Comment = "Happy Tools STARTED" });
                }));
            }
        });

        Thread thread = new Thread(job);
        thread.Start();



        //The another minute of processing here.....
punkouter
  • 5,170
  • 15
  • 71
  • 116
  • Well that's how it is. Until the collection is updated the UI won't reflect it. – Versatile May 14 '15 at 16:51
  • Is it on the same thread? – Felix Castor May 14 '15 at 16:52
  • I think it has something to do with Thread vs. UI thread? It is not just the datagrid.. It is any GUI.. none of it is updated until control is given back to the user – punkouter May 14 '15 at 17:28
  • The collection is updated when I do an .add right? I am just waiting for the UI that is binded to that collection to happen – punkouter May 14 '15 at 17:29
  • @punkouter When there are comments from more then 1 person on your post, you should use [@username ping](http://meta.stackexchange.com/questions/43019/how-do-comment-replies-work) to notify them about your new comment, because they won't get any notification otherwise and not everybody continues to poll questions one have commented upon earlier. – Eugene Podskal May 14 '15 at 17:32
  • @punkouter And do you use any thread, tasks, async or background workers to do the job or not? If not, then UI won't be updated until the event, that started collection modification, is handled. – Eugene Podskal May 14 '15 at 17:33
  • http://stackoverflow.com/questions/2091988/how-do-i-update-an-observablecollection-via-a-worker-thread may give you a few ideas about how to unproblematically modify ObservableCollection from other thread (or with async-await context preservation). http://stackoverflow.com/questions/9602567/how-to-update-ui-from-another-thread-running-in-another-class can also be of some use for you. – Eugene Podskal May 14 '15 at 17:36
  • @EugenePodskal no I don't so I guess I am doing it wrong. Ill take a look at that link thanks – punkouter May 14 '15 at 18:20
  • I found a one liner but that does not change the UI right away either.. I had trouble with the other explanations. I just want something simple.. I am ok if it is not best practice. I just want to update the datagrid with 'Status' throughout the processing.. There must be a simple way to said 'Just give me the UI thread real quick to print this' – punkouter May 14 '15 at 18:44
  • You may want to look at DispatcherThread if you want the UI to have some breathing space and let it refresh. – Versatile May 14 '15 at 20:41
  • @punkouter What do you mean by "Still does not update the UI until the end though"? Adding 20 lightweight items may easily look as one operation. Try to put `Thread.Sleep(1000);` before `Dispatcher.Invoke` and you will see the difference for sure. – Eugene Podskal May 14 '15 at 21:39
  • @EugenePodskal Ok. I did not have a sleep. Maybe that is the piece I am missing. – punkouter May 15 '15 at 14:51
  • Adding `Sleep` will simulate that adding(creating) single item takes some time. Otherwise, if it takes very little time to create and add even multiple new items, then there is no real need to use any of the parallel(async) programming constructs for now. – Eugene Podskal May 15 '15 at 15:05
  • @EugenePodskal I think I need to read some basics and give it one more shot. Ill paste my next attempt later .. this shouldn't be so complex I would think.. – punkouter May 15 '15 at 18:57
  • @punkouter If you see that you can't elaborate the problem verbally and with small separate code snippets, then it is a right time to consider creation of [Minimal Complete Verifiable Example](http://stackoverflow.com/help/mcve). – Eugene Podskal May 15 '15 at 19:15

1 Answers1

0

I made the mistake of asking a question without understanding the basics and therefore coding all over the place not sure what I was doing. So I think I got it now. The article that helped my simple mind understand it is here..

The main point is to understand WPF has a main thread and a UI thread and how to go from one to the other to allow access to the UI.

http://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/

punkouter
  • 5,170
  • 15
  • 71
  • 116